mirror of https://github.com/gophish/gophish
Localization base features development (Golang & JS), further need is definieng the localization string both in golang translation file and html pages.
parent
dbadac3eca
commit
563368d64c
|
@ -1,7 +1,7 @@
|
||||||
{
|
{
|
||||||
"admin_server" : {
|
"admin_server" : {
|
||||||
"listen_url" : "127.0.0.1:3333",
|
"listen_url" : "0.0.0.0:3333",
|
||||||
"use_tls" : true,
|
"use_tls" : false,
|
||||||
"cert_path" : "gophish_admin.crt",
|
"cert_path" : "gophish_admin.crt",
|
||||||
"key_path" : "gophish_admin.key"
|
"key_path" : "gophish_admin.key"
|
||||||
},
|
},
|
||||||
|
|
|
@ -16,11 +16,11 @@ import (
|
||||||
"github.com/gophish/gophish/auth"
|
"github.com/gophish/gophish/auth"
|
||||||
ctx "github.com/gophish/gophish/context"
|
ctx "github.com/gophish/gophish/context"
|
||||||
"github.com/gophish/gophish/models"
|
"github.com/gophish/gophish/models"
|
||||||
"github.com/gophish/gophish/util"
|
|
||||||
"github.com/gophish/gophish/worker"
|
"github.com/gophish/gophish/worker"
|
||||||
"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/email"
|
||||||
|
"../util"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Worker is the worker that processes phishing events and updates campaigns.
|
// Worker is the worker that processes phishing events and updates campaigns.
|
||||||
|
@ -52,9 +52,9 @@ func API_Reset(w http.ResponseWriter, r *http.Request) {
|
||||||
u.ApiKey = auth.GenerateSecureKey()
|
u.ApiKey = auth.GenerateSecureKey()
|
||||||
err := models.PutUser(&u)
|
err := models.PutUser(&u)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
http.Error(w, "Error setting API Key", http.StatusInternalServerError)
|
http.Error(w, util.T("Error setting API Key"), http.StatusInternalServerError)
|
||||||
} else {
|
} else {
|
||||||
JSONResponse(w, models.Response{Success: true, Message: "API Key successfully reset!", Data: u.ApiKey}, http.StatusOK)
|
JSONResponse(w, models.Response{Success: true, Message: util.T("API Key successfully reset!"), Data: u.ApiKey}, http.StatusOK)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -109,7 +109,7 @@ func API_Campaigns_Id(w http.ResponseWriter, r *http.Request) {
|
||||||
c, err := models.GetCampaign(id, ctx.Get(r, "user_id").(int64))
|
c, err := models.GetCampaign(id, ctx.Get(r, "user_id").(int64))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
Logger.Println(err)
|
Logger.Println(err)
|
||||||
JSONResponse(w, models.Response{Success: false, Message: "Campaign not found"}, http.StatusNotFound)
|
JSONResponse(w, models.Response{Success: false, Message: util.T("Campaign not found")}, http.StatusNotFound)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
switch {
|
switch {
|
||||||
|
@ -118,10 +118,10 @@ func API_Campaigns_Id(w http.ResponseWriter, r *http.Request) {
|
||||||
case r.Method == "DELETE":
|
case r.Method == "DELETE":
|
||||||
err = models.DeleteCampaign(id)
|
err = models.DeleteCampaign(id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
JSONResponse(w, models.Response{Success: false, Message: "Error deleting campaign"}, http.StatusInternalServerError)
|
JSONResponse(w, models.Response{Success: false, Message: util.T("Error deleting campaign")}, http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
JSONResponse(w, models.Response{Success: true, Message: "Campaign deleted successfully!"}, http.StatusOK)
|
JSONResponse(w, models.Response{Success: true, Message: util.T("Campaign deleted successfully!")}, http.StatusOK)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -133,7 +133,7 @@ func API_Campaigns_Id_Results(w http.ResponseWriter, r *http.Request) {
|
||||||
cr, err := models.GetCampaignResults(id, ctx.Get(r, "user_id").(int64))
|
cr, err := models.GetCampaignResults(id, ctx.Get(r, "user_id").(int64))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
Logger.Println(err)
|
Logger.Println(err)
|
||||||
JSONResponse(w, models.Response{Success: false, Message: "Campaign not found"}, http.StatusNotFound)
|
JSONResponse(w, models.Response{Success: false, Message: util.T("Campaign not found")}, http.StatusNotFound)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if r.Method == "GET" {
|
if r.Method == "GET" {
|
||||||
|
@ -151,9 +151,9 @@ func API_Campaign_Id_Summary(w http.ResponseWriter, r *http.Request) {
|
||||||
cs, err := models.GetCampaignSummary(id, ctx.Get(r, "user_id").(int64))
|
cs, err := models.GetCampaignSummary(id, ctx.Get(r, "user_id").(int64))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if err == gorm.ErrRecordNotFound {
|
if err == gorm.ErrRecordNotFound {
|
||||||
JSONResponse(w, models.Response{Success: false, Message: "Campaign not found"}, http.StatusNotFound)
|
JSONResponse(w, models.Response{Success: false, Message: util.T("Campaign not found")}, http.StatusNotFound)
|
||||||
} else {
|
} else {
|
||||||
JSONResponse(w, models.Response{Success: false, Message: err.Error()}, http.StatusInternalServerError)
|
JSONResponse(w, models.Response{Success: false, Message: util.T(err.Error())}, http.StatusInternalServerError)
|
||||||
}
|
}
|
||||||
Logger.Println(err)
|
Logger.Println(err)
|
||||||
return
|
return
|
||||||
|
@ -171,10 +171,10 @@ func API_Campaigns_Id_Complete(w http.ResponseWriter, r *http.Request) {
|
||||||
case r.Method == "GET":
|
case r.Method == "GET":
|
||||||
err := models.CompleteCampaign(id, ctx.Get(r, "user_id").(int64))
|
err := models.CompleteCampaign(id, ctx.Get(r, "user_id").(int64))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
JSONResponse(w, models.Response{Success: false, Message: "Error completing campaign"}, http.StatusInternalServerError)
|
JSONResponse(w, models.Response{Success: false, Message: util.T("Error completing campaign")}, http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
JSONResponse(w, models.Response{Success: true, Message: "Campaign completed successfully!"}, http.StatusOK)
|
JSONResponse(w, models.Response{Success: true, Message: util.T("Campaign completed successfully!")}, http.StatusOK)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -185,7 +185,7 @@ func API_Groups(w http.ResponseWriter, r *http.Request) {
|
||||||
case r.Method == "GET":
|
case r.Method == "GET":
|
||||||
gs, err := models.GetGroups(ctx.Get(r, "user_id").(int64))
|
gs, err := models.GetGroups(ctx.Get(r, "user_id").(int64))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
JSONResponse(w, models.Response{Success: false, Message: "No groups found"}, http.StatusNotFound)
|
JSONResponse(w, models.Response{Success: false, Message: util.T("No groups found")}, http.StatusNotFound)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
JSONResponse(w, gs, http.StatusOK)
|
JSONResponse(w, gs, http.StatusOK)
|
||||||
|
@ -195,12 +195,12 @@ func API_Groups(w http.ResponseWriter, r *http.Request) {
|
||||||
// Put the request into a group
|
// Put the request into a group
|
||||||
err := json.NewDecoder(r.Body).Decode(&g)
|
err := json.NewDecoder(r.Body).Decode(&g)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
JSONResponse(w, models.Response{Success: false, Message: "Invalid JSON structure"}, http.StatusBadRequest)
|
JSONResponse(w, models.Response{Success: false, Message: util.T("Invalid JSON structure")}, http.StatusBadRequest)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
_, err = models.GetGroupByName(g.Name, ctx.Get(r, "user_id").(int64))
|
_, err = models.GetGroupByName(g.Name, ctx.Get(r, "user_id").(int64))
|
||||||
if err != gorm.ErrRecordNotFound {
|
if err != gorm.ErrRecordNotFound {
|
||||||
JSONResponse(w, models.Response{Success: false, Message: "Group name already in use"}, http.StatusConflict)
|
JSONResponse(w, models.Response{Success: false, Message: util.T("Group name already in use")}, http.StatusConflict)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
g.ModifiedDate = time.Now()
|
g.ModifiedDate = time.Now()
|
||||||
|
@ -235,7 +235,7 @@ func API_Groups_Id(w http.ResponseWriter, r *http.Request) {
|
||||||
id, _ := strconv.ParseInt(vars["id"], 0, 64)
|
id, _ := strconv.ParseInt(vars["id"], 0, 64)
|
||||||
g, err := models.GetGroup(id, ctx.Get(r, "user_id").(int64))
|
g, err := models.GetGroup(id, ctx.Get(r, "user_id").(int64))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
JSONResponse(w, models.Response{Success: false, Message: "Group not found"}, http.StatusNotFound)
|
JSONResponse(w, models.Response{Success: false, Message: util.T("Group not found")}, http.StatusNotFound)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
switch {
|
switch {
|
||||||
|
@ -244,23 +244,23 @@ func API_Groups_Id(w http.ResponseWriter, r *http.Request) {
|
||||||
case r.Method == "DELETE":
|
case r.Method == "DELETE":
|
||||||
err = models.DeleteGroup(&g)
|
err = models.DeleteGroup(&g)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
JSONResponse(w, models.Response{Success: false, Message: "Error deleting group"}, http.StatusInternalServerError)
|
JSONResponse(w, models.Response{Success: false, Message: util.T("Error deleting group")}, http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
JSONResponse(w, models.Response{Success: true, Message: "Group deleted successfully!"}, http.StatusOK)
|
JSONResponse(w, models.Response{Success: true, Message: util.T("Group deleted successfully!")}, http.StatusOK)
|
||||||
case r.Method == "PUT":
|
case r.Method == "PUT":
|
||||||
// Change this to get from URL and uid (don't bother with id in r.Body)
|
// Change this to get from URL and uid (don't bother with id in r.Body)
|
||||||
g = models.Group{}
|
g = models.Group{}
|
||||||
err = json.NewDecoder(r.Body).Decode(&g)
|
err = json.NewDecoder(r.Body).Decode(&g)
|
||||||
if g.Id != id {
|
if g.Id != id {
|
||||||
JSONResponse(w, models.Response{Success: false, Message: "Error: /:id and group_id mismatch"}, http.StatusInternalServerError)
|
JSONResponse(w, models.Response{Success: false, Message: util.T("Error: /:id and group_id mismatch")}, http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
g.ModifiedDate = time.Now()
|
g.ModifiedDate = time.Now()
|
||||||
g.UserId = ctx.Get(r, "user_id").(int64)
|
g.UserId = ctx.Get(r, "user_id").(int64)
|
||||||
err = models.PutGroup(&g)
|
err = models.PutGroup(&g)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
JSONResponse(w, models.Response{Success: false, Message: err.Error()}, http.StatusBadRequest)
|
JSONResponse(w, models.Response{Success: false, Message: util.T(err.Error())}, http.StatusBadRequest)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
JSONResponse(w, g, http.StatusOK)
|
JSONResponse(w, g, http.StatusOK)
|
||||||
|
@ -275,7 +275,7 @@ func API_Groups_Id_Summary(w http.ResponseWriter, r *http.Request) {
|
||||||
id, _ := strconv.ParseInt(vars["id"], 0, 64)
|
id, _ := strconv.ParseInt(vars["id"], 0, 64)
|
||||||
g, err := models.GetGroupSummary(id, ctx.Get(r, "user_id").(int64))
|
g, err := models.GetGroupSummary(id, ctx.Get(r, "user_id").(int64))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
JSONResponse(w, models.Response{Success: false, Message: "Group not found"}, http.StatusNotFound)
|
JSONResponse(w, models.Response{Success: false, Message: util.T("Group not found")}, http.StatusNotFound)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
JSONResponse(w, g, http.StatusOK)
|
JSONResponse(w, g, http.StatusOK)
|
||||||
|
@ -297,27 +297,27 @@ func API_Templates(w http.ResponseWriter, r *http.Request) {
|
||||||
// Put the request into a template
|
// Put the request into a template
|
||||||
err := json.NewDecoder(r.Body).Decode(&t)
|
err := json.NewDecoder(r.Body).Decode(&t)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
JSONResponse(w, models.Response{Success: false, Message: "Invalid JSON structure"}, http.StatusBadRequest)
|
JSONResponse(w, models.Response{Success: false, Message: util.T("Invalid JSON structure")}, http.StatusBadRequest)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
_, err = models.GetTemplateByName(t.Name, ctx.Get(r, "user_id").(int64))
|
_, err = models.GetTemplateByName(t.Name, ctx.Get(r, "user_id").(int64))
|
||||||
if err != gorm.ErrRecordNotFound {
|
if err != gorm.ErrRecordNotFound {
|
||||||
JSONResponse(w, models.Response{Success: false, Message: "Template name already in use"}, http.StatusConflict)
|
JSONResponse(w, models.Response{Success: false, Message: util.T("Template name already in use")}, http.StatusConflict)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
t.ModifiedDate = time.Now()
|
t.ModifiedDate = time.Now()
|
||||||
t.UserId = ctx.Get(r, "user_id").(int64)
|
t.UserId = ctx.Get(r, "user_id").(int64)
|
||||||
err = models.PostTemplate(&t)
|
err = models.PostTemplate(&t)
|
||||||
if err == models.ErrTemplateNameNotSpecified {
|
if err == models.ErrTemplateNameNotSpecified {
|
||||||
JSONResponse(w, models.Response{Success: false, Message: err.Error()}, http.StatusBadRequest)
|
JSONResponse(w, models.Response{Success: false, Message: util.T(err.Error())}, http.StatusBadRequest)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if err == models.ErrTemplateMissingParameter {
|
if err == models.ErrTemplateMissingParameter {
|
||||||
JSONResponse(w, models.Response{Success: false, Message: err.Error()}, http.StatusBadRequest)
|
JSONResponse(w, models.Response{Success: false, Message: util.T(err.Error())}, http.StatusBadRequest)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
JSONResponse(w, models.Response{Success: false, Message: "Error inserting template into database"}, http.StatusInternalServerError)
|
JSONResponse(w, models.Response{Success: false, Message: util.T("Error inserting template into database")}, http.StatusInternalServerError)
|
||||||
Logger.Println(err)
|
Logger.Println(err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -331,7 +331,7 @@ func API_Templates_Id(w http.ResponseWriter, r *http.Request) {
|
||||||
id, _ := strconv.ParseInt(vars["id"], 0, 64)
|
id, _ := strconv.ParseInt(vars["id"], 0, 64)
|
||||||
t, err := models.GetTemplate(id, ctx.Get(r, "user_id").(int64))
|
t, err := models.GetTemplate(id, ctx.Get(r, "user_id").(int64))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
JSONResponse(w, models.Response{Success: false, Message: "Template not found"}, http.StatusNotFound)
|
JSONResponse(w, models.Response{Success: false, Message: util.T("Template not found")}, http.StatusNotFound)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
switch {
|
switch {
|
||||||
|
@ -340,10 +340,10 @@ func API_Templates_Id(w http.ResponseWriter, r *http.Request) {
|
||||||
case r.Method == "DELETE":
|
case r.Method == "DELETE":
|
||||||
err = models.DeleteTemplate(id, ctx.Get(r, "user_id").(int64))
|
err = models.DeleteTemplate(id, ctx.Get(r, "user_id").(int64))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
JSONResponse(w, models.Response{Success: false, Message: "Error deleting template"}, http.StatusInternalServerError)
|
JSONResponse(w, models.Response{Success: false, Message: util.T("Error deleting template")}, http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
JSONResponse(w, models.Response{Success: true, Message: "Template deleted successfully!"}, http.StatusOK)
|
JSONResponse(w, models.Response{Success: true, Message: util.T("Template deleted successfully!")}, http.StatusOK)
|
||||||
case r.Method == "PUT":
|
case r.Method == "PUT":
|
||||||
t = models.Template{}
|
t = models.Template{}
|
||||||
err = json.NewDecoder(r.Body).Decode(&t)
|
err = json.NewDecoder(r.Body).Decode(&t)
|
||||||
|
@ -351,14 +351,14 @@ func API_Templates_Id(w http.ResponseWriter, r *http.Request) {
|
||||||
Logger.Println(err)
|
Logger.Println(err)
|
||||||
}
|
}
|
||||||
if t.Id != id {
|
if t.Id != id {
|
||||||
JSONResponse(w, models.Response{Success: false, Message: "Error: /:id and template_id mismatch"}, http.StatusBadRequest)
|
JSONResponse(w, models.Response{Success: false, Message: util.T("Error: /:id and template_id mismatch")}, http.StatusBadRequest)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
t.ModifiedDate = time.Now()
|
t.ModifiedDate = time.Now()
|
||||||
t.UserId = ctx.Get(r, "user_id").(int64)
|
t.UserId = ctx.Get(r, "user_id").(int64)
|
||||||
err = models.PutTemplate(&t)
|
err = models.PutTemplate(&t)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
JSONResponse(w, models.Response{Success: false, Message: err.Error()}, http.StatusBadRequest)
|
JSONResponse(w, models.Response{Success: false, Message: util.T(err.Error())}, http.StatusBadRequest)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
JSONResponse(w, t, http.StatusOK)
|
JSONResponse(w, t, http.StatusOK)
|
||||||
|
@ -380,13 +380,13 @@ func API_Pages(w http.ResponseWriter, r *http.Request) {
|
||||||
// Put the request into a page
|
// Put the request into a page
|
||||||
err := json.NewDecoder(r.Body).Decode(&p)
|
err := json.NewDecoder(r.Body).Decode(&p)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
JSONResponse(w, models.Response{Success: false, Message: "Invalid request"}, http.StatusBadRequest)
|
JSONResponse(w, models.Response{Success: false, Message: util.T("Invalid request")}, http.StatusBadRequest)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
// Check to make sure the name is unique
|
// Check to make sure the name is unique
|
||||||
_, err = models.GetPageByName(p.Name, ctx.Get(r, "user_id").(int64))
|
_, err = models.GetPageByName(p.Name, ctx.Get(r, "user_id").(int64))
|
||||||
if err != gorm.ErrRecordNotFound {
|
if err != gorm.ErrRecordNotFound {
|
||||||
JSONResponse(w, models.Response{Success: false, Message: "Page name already in use"}, http.StatusConflict)
|
JSONResponse(w, models.Response{Success: false, Message: util.T("Page name already in use")}, http.StatusConflict)
|
||||||
Logger.Println(err)
|
Logger.Println(err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -394,7 +394,7 @@ func API_Pages(w http.ResponseWriter, r *http.Request) {
|
||||||
p.UserId = ctx.Get(r, "user_id").(int64)
|
p.UserId = ctx.Get(r, "user_id").(int64)
|
||||||
err = models.PostPage(&p)
|
err = models.PostPage(&p)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
JSONResponse(w, models.Response{Success: false, Message: err.Error()}, http.StatusInternalServerError)
|
JSONResponse(w, models.Response{Success: false, Message: util.T(err.Error())}, http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
JSONResponse(w, p, http.StatusCreated)
|
JSONResponse(w, p, http.StatusCreated)
|
||||||
|
@ -408,7 +408,7 @@ func API_Pages_Id(w http.ResponseWriter, r *http.Request) {
|
||||||
id, _ := strconv.ParseInt(vars["id"], 0, 64)
|
id, _ := strconv.ParseInt(vars["id"], 0, 64)
|
||||||
p, err := models.GetPage(id, ctx.Get(r, "user_id").(int64))
|
p, err := models.GetPage(id, ctx.Get(r, "user_id").(int64))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
JSONResponse(w, models.Response{Success: false, Message: "Page not found"}, http.StatusNotFound)
|
JSONResponse(w, models.Response{Success: false, Message: util.T("Page not found")}, http.StatusNotFound)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
switch {
|
switch {
|
||||||
|
@ -417,10 +417,10 @@ func API_Pages_Id(w http.ResponseWriter, r *http.Request) {
|
||||||
case r.Method == "DELETE":
|
case r.Method == "DELETE":
|
||||||
err = models.DeletePage(id, ctx.Get(r, "user_id").(int64))
|
err = models.DeletePage(id, ctx.Get(r, "user_id").(int64))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
JSONResponse(w, models.Response{Success: false, Message: "Error deleting page"}, http.StatusInternalServerError)
|
JSONResponse(w, models.Response{Success: false, Message: util.T("Error deleting page")}, http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
JSONResponse(w, models.Response{Success: true, Message: "Page Deleted Successfully"}, http.StatusOK)
|
JSONResponse(w, models.Response{Success: true, Message: util.T("Page Deleted Successfully")}, http.StatusOK)
|
||||||
case r.Method == "PUT":
|
case r.Method == "PUT":
|
||||||
p = models.Page{}
|
p = models.Page{}
|
||||||
err = json.NewDecoder(r.Body).Decode(&p)
|
err = json.NewDecoder(r.Body).Decode(&p)
|
||||||
|
@ -428,14 +428,14 @@ func API_Pages_Id(w http.ResponseWriter, r *http.Request) {
|
||||||
Logger.Println(err)
|
Logger.Println(err)
|
||||||
}
|
}
|
||||||
if p.Id != id {
|
if p.Id != id {
|
||||||
JSONResponse(w, models.Response{Success: false, Message: "/:id and /:page_id mismatch"}, http.StatusBadRequest)
|
JSONResponse(w, models.Response{Success: false, Message: util.T("/:id and /:page_id mismatch")}, http.StatusBadRequest)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
p.ModifiedDate = time.Now()
|
p.ModifiedDate = time.Now()
|
||||||
p.UserId = ctx.Get(r, "user_id").(int64)
|
p.UserId = ctx.Get(r, "user_id").(int64)
|
||||||
err = models.PutPage(&p)
|
err = models.PutPage(&p)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
JSONResponse(w, models.Response{Success: false, Message: "Error updating page: " + err.Error()}, http.StatusInternalServerError)
|
JSONResponse(w, models.Response{Success: false, Message: util.T("Error updating page: " + err.Error())}, http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
JSONResponse(w, p, http.StatusOK)
|
JSONResponse(w, p, http.StatusOK)
|
||||||
|
@ -457,13 +457,13 @@ func API_SMTP(w http.ResponseWriter, r *http.Request) {
|
||||||
// Put the request into a page
|
// Put the request into a page
|
||||||
err := json.NewDecoder(r.Body).Decode(&s)
|
err := json.NewDecoder(r.Body).Decode(&s)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
JSONResponse(w, models.Response{Success: false, Message: "Invalid request"}, http.StatusBadRequest)
|
JSONResponse(w, models.Response{Success: false, Message: util.T("Invalid request")}, http.StatusBadRequest)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
// Check to make sure the name is unique
|
// Check to make sure the name is unique
|
||||||
_, err = models.GetSMTPByName(s.Name, ctx.Get(r, "user_id").(int64))
|
_, err = models.GetSMTPByName(s.Name, ctx.Get(r, "user_id").(int64))
|
||||||
if err != gorm.ErrRecordNotFound {
|
if err != gorm.ErrRecordNotFound {
|
||||||
JSONResponse(w, models.Response{Success: false, Message: "SMTP name already in use"}, http.StatusConflict)
|
JSONResponse(w, models.Response{Success: false, Message: util.T("SMTP name already in use")}, http.StatusConflict)
|
||||||
Logger.Println(err)
|
Logger.Println(err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -471,7 +471,7 @@ func API_SMTP(w http.ResponseWriter, r *http.Request) {
|
||||||
s.UserId = ctx.Get(r, "user_id").(int64)
|
s.UserId = ctx.Get(r, "user_id").(int64)
|
||||||
err = models.PostSMTP(&s)
|
err = models.PostSMTP(&s)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
JSONResponse(w, models.Response{Success: false, Message: err.Error()}, http.StatusInternalServerError)
|
JSONResponse(w, models.Response{Success: false, Message: util.T(err.Error())}, http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
JSONResponse(w, s, http.StatusCreated)
|
JSONResponse(w, s, http.StatusCreated)
|
||||||
|
@ -485,7 +485,7 @@ func API_SMTP_Id(w http.ResponseWriter, r *http.Request) {
|
||||||
id, _ := strconv.ParseInt(vars["id"], 0, 64)
|
id, _ := strconv.ParseInt(vars["id"], 0, 64)
|
||||||
s, err := models.GetSMTP(id, ctx.Get(r, "user_id").(int64))
|
s, err := models.GetSMTP(id, ctx.Get(r, "user_id").(int64))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
JSONResponse(w, models.Response{Success: false, Message: "SMTP not found"}, http.StatusNotFound)
|
JSONResponse(w, models.Response{Success: false, Message: util.T("SMTP not found")}, http.StatusNotFound)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
switch {
|
switch {
|
||||||
|
@ -494,10 +494,10 @@ func API_SMTP_Id(w http.ResponseWriter, r *http.Request) {
|
||||||
case r.Method == "DELETE":
|
case r.Method == "DELETE":
|
||||||
err = models.DeleteSMTP(id, ctx.Get(r, "user_id").(int64))
|
err = models.DeleteSMTP(id, ctx.Get(r, "user_id").(int64))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
JSONResponse(w, models.Response{Success: false, Message: "Error deleting SMTP"}, http.StatusInternalServerError)
|
JSONResponse(w, models.Response{Success: false, Message: util.T("Error deleting SMTP")}, http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
JSONResponse(w, models.Response{Success: true, Message: "SMTP Deleted Successfully"}, http.StatusOK)
|
JSONResponse(w, models.Response{Success: true, Message: util.T("SMTP Deleted Successfully")}, http.StatusOK)
|
||||||
case r.Method == "PUT":
|
case r.Method == "PUT":
|
||||||
s = models.SMTP{}
|
s = models.SMTP{}
|
||||||
err = json.NewDecoder(r.Body).Decode(&s)
|
err = json.NewDecoder(r.Body).Decode(&s)
|
||||||
|
@ -505,19 +505,19 @@ func API_SMTP_Id(w http.ResponseWriter, r *http.Request) {
|
||||||
Logger.Println(err)
|
Logger.Println(err)
|
||||||
}
|
}
|
||||||
if s.Id != id {
|
if s.Id != id {
|
||||||
JSONResponse(w, models.Response{Success: false, Message: "/:id and /:smtp_id mismatch"}, http.StatusBadRequest)
|
JSONResponse(w, models.Response{Success: false, Message: util.T("/:id and /:smtp_id mismatch")}, http.StatusBadRequest)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
err = s.Validate()
|
err = s.Validate()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
JSONResponse(w, models.Response{Success: false, Message: err.Error()}, http.StatusBadRequest)
|
JSONResponse(w, models.Response{Success: false, Message: util.T(err.Error())}, http.StatusBadRequest)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
s.ModifiedDate = time.Now()
|
s.ModifiedDate = time.Now()
|
||||||
s.UserId = ctx.Get(r, "user_id").(int64)
|
s.UserId = ctx.Get(r, "user_id").(int64)
|
||||||
err = models.PutSMTP(&s)
|
err = models.PutSMTP(&s)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
JSONResponse(w, models.Response{Success: false, Message: "Error updating page"}, http.StatusInternalServerError)
|
JSONResponse(w, models.Response{Success: false, Message: util.T("Error updating page")}, http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
JSONResponse(w, s, http.StatusOK)
|
JSONResponse(w, s, http.StatusOK)
|
||||||
|
@ -528,7 +528,7 @@ func API_SMTP_Id(w http.ResponseWriter, r *http.Request) {
|
||||||
func API_Import_Group(w http.ResponseWriter, r *http.Request) {
|
func API_Import_Group(w http.ResponseWriter, r *http.Request) {
|
||||||
ts, err := util.ParseCSV(r)
|
ts, err := util.ParseCSV(r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
JSONResponse(w, models.Response{Success: false, Message: "Error parsing CSV"}, http.StatusInternalServerError)
|
JSONResponse(w, models.Response{Success: false, Message: util.T("Error parsing CSV")}, http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
JSONResponse(w, ts, http.StatusOK)
|
JSONResponse(w, ts, http.StatusOK)
|
||||||
|
@ -539,7 +539,7 @@ func API_Import_Group(w http.ResponseWriter, r *http.Request) {
|
||||||
// Returns a Message object
|
// Returns a Message object
|
||||||
func API_Import_Email(w http.ResponseWriter, r *http.Request) {
|
func API_Import_Email(w http.ResponseWriter, r *http.Request) {
|
||||||
if r.Method != "POST" {
|
if r.Method != "POST" {
|
||||||
JSONResponse(w, models.Response{Success: false, Message: "Method not allowed"}, http.StatusBadRequest)
|
JSONResponse(w, models.Response{Success: false, Message: util.T("Method not allowed")}, http.StatusBadRequest)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
ir := struct {
|
ir := struct {
|
||||||
|
@ -548,7 +548,7 @@ func API_Import_Email(w http.ResponseWriter, r *http.Request) {
|
||||||
}{}
|
}{}
|
||||||
err := json.NewDecoder(r.Body).Decode(&ir)
|
err := json.NewDecoder(r.Body).Decode(&ir)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
JSONResponse(w, models.Response{Success: false, Message: "Error decoding JSON Request"}, http.StatusBadRequest)
|
JSONResponse(w, models.Response{Success: false, Message: util.T("Error decoding JSON Request")}, http.StatusBadRequest)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
e, err := email.NewEmailFromReader(strings.NewReader(ir.Content))
|
e, err := email.NewEmailFromReader(strings.NewReader(ir.Content))
|
||||||
|
@ -561,7 +561,7 @@ func API_Import_Email(w http.ResponseWriter, r *http.Request) {
|
||||||
if ir.ConvertLinks {
|
if ir.ConvertLinks {
|
||||||
d, err := goquery.NewDocumentFromReader(bytes.NewReader(e.HTML))
|
d, err := goquery.NewDocumentFromReader(bytes.NewReader(e.HTML))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
JSONResponse(w, models.Response{Success: false, Message: err.Error()}, http.StatusBadRequest)
|
JSONResponse(w, models.Response{Success: false, Message: util.T(err.Error())}, http.StatusBadRequest)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
d.Find("a").Each(func(i int, a *goquery.Selection) {
|
d.Find("a").Each(func(i int, a *goquery.Selection) {
|
||||||
|
@ -569,7 +569,7 @@ func API_Import_Email(w http.ResponseWriter, r *http.Request) {
|
||||||
})
|
})
|
||||||
h, err := d.Html()
|
h, err := d.Html()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
JSONResponse(w, models.Response{Success: false, Message: err.Error()}, http.StatusInternalServerError)
|
JSONResponse(w, models.Response{Success: false, Message: util.T(err.Error())}, http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
e.HTML = []byte(h)
|
e.HTML = []byte(h)
|
||||||
|
@ -589,16 +589,16 @@ func API_Import_Email(w http.ResponseWriter, r *http.Request) {
|
||||||
func API_Import_Site(w http.ResponseWriter, r *http.Request) {
|
func API_Import_Site(w http.ResponseWriter, r *http.Request) {
|
||||||
cr := cloneRequest{}
|
cr := cloneRequest{}
|
||||||
if r.Method != "POST" {
|
if r.Method != "POST" {
|
||||||
JSONResponse(w, models.Response{Success: false, Message: "Method not allowed"}, http.StatusBadRequest)
|
JSONResponse(w, models.Response{Success: false, Message: util.T("Method not allowed")}, http.StatusBadRequest)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
err := json.NewDecoder(r.Body).Decode(&cr)
|
err := json.NewDecoder(r.Body).Decode(&cr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
JSONResponse(w, models.Response{Success: false, Message: "Error decoding JSON Request"}, http.StatusBadRequest)
|
JSONResponse(w, models.Response{Success: false, Message: util.T("Error decoding JSON Request")}, http.StatusBadRequest)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if err = cr.validate(); err != nil {
|
if err = cr.validate(); err != nil {
|
||||||
JSONResponse(w, models.Response{Success: false, Message: err.Error()}, http.StatusBadRequest)
|
JSONResponse(w, models.Response{Success: false, Message: util.T(err.Error())}, http.StatusBadRequest)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
tr := &http.Transport{
|
tr := &http.Transport{
|
||||||
|
@ -609,13 +609,13 @@ func API_Import_Site(w http.ResponseWriter, r *http.Request) {
|
||||||
client := &http.Client{Transport: tr}
|
client := &http.Client{Transport: tr}
|
||||||
resp, err := client.Get(cr.URL)
|
resp, err := client.Get(cr.URL)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
JSONResponse(w, models.Response{Success: false, Message: err.Error()}, http.StatusBadRequest)
|
JSONResponse(w, models.Response{Success: false, Message: util.T(err.Error())}, http.StatusBadRequest)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
// Insert the base href tag to better handle relative resources
|
// Insert the base href tag to better handle relative resources
|
||||||
d, err := goquery.NewDocumentFromResponse(resp)
|
d, err := goquery.NewDocumentFromResponse(resp)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
JSONResponse(w, models.Response{Success: false, Message: err.Error()}, http.StatusBadRequest)
|
JSONResponse(w, models.Response{Success: false, Message: util.T(err.Error())}, http.StatusBadRequest)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
// Assuming we don't want to include resources, we'll need a base href
|
// Assuming we don't want to include resources, we'll need a base href
|
||||||
|
@ -634,7 +634,7 @@ func API_Import_Site(w http.ResponseWriter, r *http.Request) {
|
||||||
})
|
})
|
||||||
h, err := d.Html()
|
h, err := d.Html()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
JSONResponse(w, models.Response{Success: false, Message: err.Error()}, http.StatusInternalServerError)
|
JSONResponse(w, models.Response{Success: false, Message: util.T(err.Error())}, http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
cs := cloneResponse{HTML: h}
|
cs := cloneResponse{HTML: h}
|
||||||
|
@ -647,17 +647,17 @@ func API_Import_Site(w http.ResponseWriter, r *http.Request) {
|
||||||
func API_Send_Test_Email(w http.ResponseWriter, r *http.Request) {
|
func API_Send_Test_Email(w http.ResponseWriter, r *http.Request) {
|
||||||
s := &models.SendTestEmailRequest{}
|
s := &models.SendTestEmailRequest{}
|
||||||
if r.Method != "POST" {
|
if r.Method != "POST" {
|
||||||
JSONResponse(w, models.Response{Success: false, Message: "Method not allowed"}, http.StatusBadRequest)
|
JSONResponse(w, models.Response{Success: false, Message: util.T("Method not allowed")}, http.StatusBadRequest)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
err := json.NewDecoder(r.Body).Decode(s)
|
err := json.NewDecoder(r.Body).Decode(s)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
JSONResponse(w, models.Response{Success: false, Message: "Error decoding JSON Request"}, http.StatusBadRequest)
|
JSONResponse(w, models.Response{Success: false, Message: util.T("Error decoding JSON Request")}, http.StatusBadRequest)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
// Validate the given request
|
// Validate the given request
|
||||||
if err = s.Validate(); err != nil {
|
if err = s.Validate(); err != nil {
|
||||||
JSONResponse(w, models.Response{Success: false, Message: err.Error()}, http.StatusBadRequest)
|
JSONResponse(w, models.Response{Success: false, Message: util.T(err.Error())}, http.StatusBadRequest)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -682,10 +682,10 @@ func API_Send_Test_Email(w http.ResponseWriter, r *http.Request) {
|
||||||
s.Template, err = models.GetTemplateByName(s.Template.Name, ctx.Get(r, "user_id").(int64))
|
s.Template, err = models.GetTemplateByName(s.Template.Name, ctx.Get(r, "user_id").(int64))
|
||||||
if err == gorm.ErrRecordNotFound {
|
if err == gorm.ErrRecordNotFound {
|
||||||
Logger.Printf("Error - Template %s does not exist", s.Template.Name)
|
Logger.Printf("Error - Template %s does not exist", s.Template.Name)
|
||||||
JSONResponse(w, models.Response{Success: false, Message: models.ErrTemplateNotFound.Error()}, http.StatusBadRequest)
|
JSONResponse(w, models.Response{Success: false, Message: util.T(models.ErrTemplateNotFound.Error())}, http.StatusBadRequest)
|
||||||
} else if err != nil {
|
} else if err != nil {
|
||||||
Logger.Println(err)
|
Logger.Println(err)
|
||||||
JSONResponse(w, models.Response{Success: false, Message: err.Error()}, http.StatusBadRequest)
|
JSONResponse(w, models.Response{Success: false, Message: util.T(err.Error())}, http.StatusBadRequest)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -696,10 +696,10 @@ func API_Send_Test_Email(w http.ResponseWriter, r *http.Request) {
|
||||||
s.SMTP, err = models.GetSMTPByName(s.SMTP.Name, ctx.Get(r, "user_id").(int64))
|
s.SMTP, err = models.GetSMTPByName(s.SMTP.Name, ctx.Get(r, "user_id").(int64))
|
||||||
if err == gorm.ErrRecordNotFound {
|
if err == gorm.ErrRecordNotFound {
|
||||||
Logger.Printf("Error - Sending profile %s does not exist", s.SMTP.Name)
|
Logger.Printf("Error - Sending profile %s does not exist", s.SMTP.Name)
|
||||||
JSONResponse(w, models.Response{Success: false, Message: models.ErrSMTPNotFound.Error()}, http.StatusBadRequest)
|
JSONResponse(w, models.Response{Success: false, Message: util.T(models.ErrSMTPNotFound.Error())}, http.StatusBadRequest)
|
||||||
} else if err != nil {
|
} else if err != nil {
|
||||||
Logger.Println(err)
|
Logger.Println(err)
|
||||||
JSONResponse(w, models.Response{Success: false, Message: err.Error()}, http.StatusBadRequest)
|
JSONResponse(w, models.Response{Success: false, Message: util.T(err.Error())}, http.StatusBadRequest)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -707,10 +707,10 @@ func API_Send_Test_Email(w http.ResponseWriter, r *http.Request) {
|
||||||
// Send the test email
|
// Send the test email
|
||||||
err = worker.SendTestEmail(s)
|
err = worker.SendTestEmail(s)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
JSONResponse(w, models.Response{Success: false, Message: err.Error()}, http.StatusInternalServerError)
|
JSONResponse(w, models.Response{Success: false, Message: util.T(err.Error())}, http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
JSONResponse(w, models.Response{Success: true, Message: "Email Sent"}, http.StatusOK)
|
JSONResponse(w, models.Response{Success: true, Message: util.T("Email Sent")}, http.StatusOK)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -21,6 +21,7 @@ import (
|
||||||
"github.com/gorilla/csrf"
|
"github.com/gorilla/csrf"
|
||||||
"github.com/gorilla/mux"
|
"github.com/gorilla/mux"
|
||||||
"github.com/gorilla/sessions"
|
"github.com/gorilla/sessions"
|
||||||
|
"../util"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Logger is used to send logging messages to stdout.
|
// Logger is used to send logging messages to stdout.
|
||||||
|
@ -241,7 +242,9 @@ func PhishHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
var htmlBuff bytes.Buffer
|
var htmlBuff bytes.Buffer
|
||||||
tmpl, err := template.New("html_template").Parse(p.HTML)
|
tmpl, err := template.New("html_template").Funcs(template.FuncMap{
|
||||||
|
"T": util.T,
|
||||||
|
}).Parse(p.HTML)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
Logger.Println(err)
|
Logger.Println(err)
|
||||||
http.NotFound(w, r)
|
http.NotFound(w, r)
|
||||||
|
@ -295,7 +298,9 @@ func Register(w http.ResponseWriter, r *http.Request) {
|
||||||
case r.Method == "GET":
|
case r.Method == "GET":
|
||||||
params.Flashes = session.Flashes()
|
params.Flashes = session.Flashes()
|
||||||
session.Save(r, w)
|
session.Save(r, w)
|
||||||
templates := template.New("template")
|
templates := template.New("template").Funcs(template.FuncMap{
|
||||||
|
"T": util.T,
|
||||||
|
})
|
||||||
_, err := templates.ParseFiles("templates/register.html", "templates/flashes.html")
|
_, err := templates.ParseFiles("templates/register.html", "templates/flashes.html")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
Logger.Println(err)
|
Logger.Println(err)
|
||||||
|
@ -455,7 +460,9 @@ func Login(w http.ResponseWriter, r *http.Request) {
|
||||||
case r.Method == "GET":
|
case r.Method == "GET":
|
||||||
params.Flashes = session.Flashes()
|
params.Flashes = session.Flashes()
|
||||||
session.Save(r, w)
|
session.Save(r, w)
|
||||||
templates := template.New("template")
|
templates := template.New("template").Funcs(template.FuncMap{
|
||||||
|
"T": util.T,
|
||||||
|
})
|
||||||
_, err := templates.ParseFiles("templates/login.html", "templates/flashes.html")
|
_, err := templates.ParseFiles("templates/login.html", "templates/flashes.html")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
Logger.Println(err)
|
Logger.Println(err)
|
||||||
|
@ -512,7 +519,9 @@ func Clone(w http.ResponseWriter, r *http.Request) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func getTemplate(w http.ResponseWriter, tmpl string) *template.Template {
|
func getTemplate(w http.ResponseWriter, tmpl string) *template.Template {
|
||||||
templates := template.New("template")
|
templates := template.New("template").Funcs(template.FuncMap{
|
||||||
|
"T": util.T,
|
||||||
|
})
|
||||||
_, err := templates.ParseFiles("templates/base.html", "templates/"+tmpl+".html", "templates/flashes.html")
|
_, err := templates.ParseFiles("templates/base.html", "templates/"+tmpl+".html", "templates/flashes.html")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
Logger.Println(err)
|
Logger.Println(err)
|
||||||
|
|
|
@ -36,16 +36,18 @@ import (
|
||||||
"github.com/NYTimes/gziphandler"
|
"github.com/NYTimes/gziphandler"
|
||||||
"github.com/gophish/gophish/auth"
|
"github.com/gophish/gophish/auth"
|
||||||
"github.com/gophish/gophish/config"
|
"github.com/gophish/gophish/config"
|
||||||
"github.com/gophish/gophish/controllers"
|
"./controllers"
|
||||||
"github.com/gophish/gophish/models"
|
"github.com/gophish/gophish/models"
|
||||||
"github.com/gophish/gophish/util"
|
"./util"
|
||||||
"github.com/gorilla/handlers"
|
"github.com/gorilla/handlers"
|
||||||
|
"github.com/nicksnyder/go-i18n/i18n"
|
||||||
)
|
)
|
||||||
|
|
||||||
var Logger = log.New(os.Stdout, " ", log.Ldate|log.Ltime|log.Lshortfile)
|
var Logger = log.New(os.Stdout, " ", log.Ldate|log.Ltime|log.Lshortfile)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
// Setup the global variables and settings
|
// Setup the global variables and settings
|
||||||
|
i18n.MustLoadTranslationFile("translations/en-US.all.json")
|
||||||
err := models.Setup()
|
err := models.Setup()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println(err)
|
fmt.Println(err)
|
||||||
|
|
|
@ -5,6 +5,7 @@ import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/jinzhu/gorm"
|
"github.com/jinzhu/gorm"
|
||||||
|
"../util"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Campaign is a struct representing a created campaign
|
// Campaign is a struct representing a created campaign
|
||||||
|
@ -65,31 +66,31 @@ type CampaignStats struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
// ErrCampaignNameNotSpecified indicates there was no template given by the user
|
// ErrCampaignNameNotSpecified indicates there was no template given by the user
|
||||||
var ErrCampaignNameNotSpecified = errors.New("Campaign name not specified")
|
var ErrCampaignNameNotSpecified = errors.New(util.T("Campaign name not specified"))
|
||||||
|
|
||||||
// ErrGroupNotSpecified indicates there was no template given by the user
|
// ErrGroupNotSpecified indicates there was no template given by the user
|
||||||
var ErrGroupNotSpecified = errors.New("No groups specified")
|
var ErrGroupNotSpecified = errors.New(util.T("No groups specified"))
|
||||||
|
|
||||||
// ErrTemplateNotSpecified indicates there was no template given by the user
|
// ErrTemplateNotSpecified indicates there was no template given by the user
|
||||||
var ErrTemplateNotSpecified = errors.New("No email template specified")
|
var ErrTemplateNotSpecified = errors.New(util.T("No email template specified"))
|
||||||
|
|
||||||
// ErrPageNotSpecified indicates a landing page was not provided for the campaign
|
// ErrPageNotSpecified indicates a landing page was not provided for the campaign
|
||||||
var ErrPageNotSpecified = errors.New("No landing page specified")
|
var ErrPageNotSpecified = errors.New(util.T("No landing page specified"))
|
||||||
|
|
||||||
// ErrSMTPNotSpecified indicates a sending profile was not provided for the campaign
|
// ErrSMTPNotSpecified indicates a sending profile was not provided for the campaign
|
||||||
var ErrSMTPNotSpecified = errors.New("No sending profile specified")
|
var ErrSMTPNotSpecified = errors.New(util.T("No sending profile specified"))
|
||||||
|
|
||||||
// ErrTemplateNotFound indicates the template specified does not exist in the database
|
// ErrTemplateNotFound indicates the template specified does not exist in the database
|
||||||
var ErrTemplateNotFound = errors.New("Template not found")
|
var ErrTemplateNotFound = errors.New(util.T("Template not found"))
|
||||||
|
|
||||||
// ErrGroupnNotFound indicates a group specified by the user does not exist in the database
|
// ErrGroupnNotFound indicates a group specified by the user does not exist in the database
|
||||||
var ErrGroupNotFound = errors.New("Group not found")
|
var ErrGroupNotFound = errors.New(util.T("Group not found"))
|
||||||
|
|
||||||
// ErrPageNotFound indicates a page specified by the user does not exist in the database
|
// ErrPageNotFound indicates a page specified by the user does not exist in the database
|
||||||
var ErrPageNotFound = errors.New("Page not found")
|
var ErrPageNotFound = errors.New(util.T("Page not found"))
|
||||||
|
|
||||||
// ErrSMTPNotFound indicates a sending profile specified by the user does not exist in the database
|
// ErrSMTPNotFound indicates a sending profile specified by the user does not exist in the database
|
||||||
var ErrSMTPNotFound = errors.New("Sending profile not found")
|
var ErrSMTPNotFound = errors.New(util.T("Sending profile not found"))
|
||||||
|
|
||||||
// Validate checks to make sure there are no invalid fields in a submitted campaign
|
// Validate checks to make sure there are no invalid fields in a submitted campaign
|
||||||
func (c *Campaign) Validate() error {
|
func (c *Campaign) Validate() error {
|
||||||
|
|
|
@ -6,6 +6,7 @@ import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/jinzhu/gorm"
|
"github.com/jinzhu/gorm"
|
||||||
|
"../util"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Group contains the fields needed for a user -> group mapping
|
// Group contains the fields needed for a user -> group mapping
|
||||||
|
@ -51,13 +52,13 @@ type Target struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
// ErrNoEmailSpecified is thrown when no email is specified for the Target
|
// ErrNoEmailSpecified is thrown when no email is specified for the Target
|
||||||
var ErrEmailNotSpecified = errors.New("No email address specified")
|
var ErrEmailNotSpecified = errors.New(util.T("No email address specified"))
|
||||||
|
|
||||||
// ErrGroupNameNotSpecified is thrown when a group name is not specified
|
// ErrGroupNameNotSpecified is thrown when a group name is not specified
|
||||||
var ErrGroupNameNotSpecified = errors.New("Group name not specified")
|
var ErrGroupNameNotSpecified = errors.New(util.T("Group name not specified"))
|
||||||
|
|
||||||
// ErrNoTargetsSpecified is thrown when no targets are specified by the user
|
// ErrNoTargetsSpecified is thrown when no targets are specified by the user
|
||||||
var ErrNoTargetsSpecified = errors.New("No targets specified")
|
var ErrNoTargetsSpecified = errors.New(util.T("No targets specified"))
|
||||||
|
|
||||||
// Validate performs validation on a group given by the user
|
// Validate performs validation on a group given by the user
|
||||||
func (g *Group) Validate() error {
|
func (g *Group) Validate() error {
|
||||||
|
|
|
@ -14,13 +14,14 @@ import (
|
||||||
"github.com/gophish/gophish/config"
|
"github.com/gophish/gophish/config"
|
||||||
"github.com/jinzhu/gorm"
|
"github.com/jinzhu/gorm"
|
||||||
_ "github.com/mattn/go-sqlite3" // Blank import needed to import sqlite3
|
_ "github.com/mattn/go-sqlite3" // Blank import needed to import sqlite3
|
||||||
|
"../util"
|
||||||
)
|
)
|
||||||
|
|
||||||
var db *gorm.DB
|
var db *gorm.DB
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
// ErrUsernameTaken is thrown when a user attempts to register a username that is taken.
|
// ErrUsernameTaken is thrown when a user attempts to register a username that is taken.
|
||||||
var ErrUsernameTaken = errors.New("username already taken")
|
var ErrUsernameTaken = errors.New(util.T("username already taken"))
|
||||||
|
|
||||||
// Logger is a global logger used to show informational, warning, and error messages
|
// Logger is a global logger used to show informational, warning, and error messages
|
||||||
var Logger = log.New(os.Stdout, " ", log.Ldate|log.Ltime|log.Lshortfile)
|
var Logger = log.New(os.Stdout, " ", log.Ldate|log.Ltime|log.Lshortfile)
|
||||||
|
|
|
@ -6,6 +6,7 @@ import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/PuerkitoBio/goquery"
|
"github.com/PuerkitoBio/goquery"
|
||||||
|
"../util"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Page contains the fields used for a Page model
|
// Page contains the fields used for a Page model
|
||||||
|
@ -21,7 +22,7 @@ type Page struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
// ErrPageNameNotSpecified is thrown if the name of the landing page is blank.
|
// ErrPageNameNotSpecified is thrown if the name of the landing page is blank.
|
||||||
var ErrPageNameNotSpecified = errors.New("Page Name not specified")
|
var ErrPageNameNotSpecified = errors.New(util.T("Page Name not specified"))
|
||||||
|
|
||||||
// parseHTML parses the page HTML on save to handle the
|
// parseHTML parses the page HTML on save to handle the
|
||||||
// capturing (or lack thereof!) of credentials and passwords
|
// capturing (or lack thereof!) of credentials and passwords
|
||||||
|
|
|
@ -8,6 +8,7 @@ import (
|
||||||
|
|
||||||
"github.com/jinzhu/gorm"
|
"github.com/jinzhu/gorm"
|
||||||
"github.com/oschwald/maxminddb-golang"
|
"github.com/oschwald/maxminddb-golang"
|
||||||
|
"../util"
|
||||||
)
|
)
|
||||||
|
|
||||||
type mmCity struct {
|
type mmCity struct {
|
||||||
|
|
|
@ -6,6 +6,7 @@ import (
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
"../util"
|
||||||
)
|
)
|
||||||
|
|
||||||
// SMTP contains the attributes needed to handle the sending of campaign emails
|
// SMTP contains the attributes needed to handle the sending of campaign emails
|
||||||
|
@ -24,14 +25,14 @@ type SMTP struct {
|
||||||
|
|
||||||
// ErrFromAddressNotSpecified is thrown when there is no "From" address
|
// ErrFromAddressNotSpecified is thrown when there is no "From" address
|
||||||
// specified in the SMTP configuration
|
// specified in the SMTP configuration
|
||||||
var ErrFromAddressNotSpecified = errors.New("No From Address specified")
|
var ErrFromAddressNotSpecified = errors.New(util.T("No From Address specified"))
|
||||||
|
|
||||||
// ErrHostNotSpecified is thrown when there is no Host specified
|
// ErrHostNotSpecified is thrown when there is no Host specified
|
||||||
// in the SMTP configuration
|
// in the SMTP configuration
|
||||||
var ErrHostNotSpecified = errors.New("No SMTP Host specified")
|
var ErrHostNotSpecified = errors.New(util.T("No SMTP Host specified"))
|
||||||
|
|
||||||
// ErrInvalidHost indicates that the SMTP server string is invalid
|
// ErrInvalidHost indicates that the SMTP server string is invalid
|
||||||
var ErrInvalidHost = errors.New("Invalid SMTP server address")
|
var ErrInvalidHost = errors.New(util.T("Invalid SMTP server address"))
|
||||||
|
|
||||||
// TableName specifies the database tablename for Gorm to use
|
// TableName specifies the database tablename for Gorm to use
|
||||||
func (s SMTP) TableName() string {
|
func (s SMTP) TableName() string {
|
||||||
|
|
|
@ -7,6 +7,7 @@ import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/jinzhu/gorm"
|
"github.com/jinzhu/gorm"
|
||||||
|
"../util"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Template models hold the attributes for an email template to be sent to targets
|
// Template models hold the attributes for an email template to be sent to targets
|
||||||
|
@ -22,10 +23,10 @@ type Template struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
// ErrTemplateNameNotSpecified is thrown when a template name is not specified
|
// ErrTemplateNameNotSpecified is thrown when a template name is not specified
|
||||||
var ErrTemplateNameNotSpecified = errors.New("Template name not specified")
|
var ErrTemplateNameNotSpecified = errors.New(util.T("Template name not specified"))
|
||||||
|
|
||||||
// ErrTemplateMissingParameter is thrown when a needed parameter is not provided
|
// ErrTemplateMissingParameter is thrown when a needed parameter is not provided
|
||||||
var ErrTemplateMissingParameter = errors.New("Need to specify at least plaintext or HTML content")
|
var ErrTemplateMissingParameter = errors.New(util.T("Need to specify at least plaintext or HTML content"))
|
||||||
|
|
||||||
// Validate checks the given template to make sure values are appropriate and complete
|
// Validate checks the given template to make sure values are appropriate and complete
|
||||||
func (t *Template) Validate() error {
|
func (t *Template) Validate() error {
|
||||||
|
|
|
@ -10,7 +10,7 @@ var labels = {
|
||||||
}
|
}
|
||||||
|
|
||||||
function deleteCampaign(idx) {
|
function deleteCampaign(idx) {
|
||||||
if (confirm("Delete " + campaigns[idx].name + "?")) {
|
if (confirm(T("Delete ") + campaigns[idx].name + "?")) {
|
||||||
api.campaignId.delete(campaigns[idx].id)
|
api.campaignId.delete(campaigns[idx].id)
|
||||||
.success(function(data) {
|
.success(function(data) {
|
||||||
successFlash(data.message)
|
successFlash(data.message)
|
||||||
|
@ -68,11 +68,11 @@ $(document).ready(function() {
|
||||||
campaignTable.row.add([
|
campaignTable.row.add([
|
||||||
escapeHtml(campaign.name),
|
escapeHtml(campaign.name),
|
||||||
campaign_date,
|
campaign_date,
|
||||||
"<span class=\"label " + label + "\">" + campaign.status + "</span>",
|
"<span class=\"label " + label + "\">" + T(campaign.status) + "</span>",
|
||||||
"<div class='pull-right'><a class='btn btn-primary' href='/campaigns/" + campaign.id + "' data-toggle='tooltip' data-placement='right' title='View Results'>\
|
"<div class='pull-right'><a class='btn btn-primary' href='/campaigns/" + campaign.id + "' data-toggle='tooltip' data-placement='right' title='" + T("View Results") +"'>\
|
||||||
<i class='fa fa-bar-chart'></i>\
|
<i class='fa fa-bar-chart'></i>\
|
||||||
</a>\
|
</a>\
|
||||||
<button class='btn btn-danger' onclick='deleteCampaign(" + i + ")' data-toggle='tooltip' data-placement='right' title='Delete Campaign'>\
|
<button class='btn btn-danger' onclick='deleteCampaign(" + i + ")' data-toggle='tooltip' data-placement='right' title='" + T("Delete Campaign") + "'>\
|
||||||
<i class='fa fa-trash-o'></i>\
|
<i class='fa fa-trash-o'></i>\
|
||||||
</button></div>"
|
</button></div>"
|
||||||
]).draw()
|
]).draw()
|
||||||
|
|
|
@ -33,7 +33,7 @@
|
||||||
<div class="container-fluid">
|
<div class="container-fluid">
|
||||||
<div class="navbar-header">
|
<div class="navbar-header">
|
||||||
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
|
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
|
||||||
<span class="sr-only">Toggle navigation</span>
|
<span class="sr-only">{{T "Toggle navigation"}}</span>
|
||||||
<span class="icon-bar"></span>
|
<span class="icon-bar"></span>
|
||||||
<span class="icon-bar"></span>
|
<span class="icon-bar"></span>
|
||||||
<span class="icon-bar"></span>
|
<span class="icon-bar"></span>
|
||||||
|
@ -43,19 +43,19 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="navbar-collapse collapse">
|
<div class="navbar-collapse collapse">
|
||||||
<ul class="nav navbar-nav navbar-right">
|
<ul class="nav navbar-nav navbar-right">
|
||||||
<li><a href="/">Dashboard</a>
|
<li><a href="/">{{T "Dashboard"}}</a>
|
||||||
</li>
|
</li>
|
||||||
<li><a href="/campaigns">Campaigns</a>
|
<li><a href="/campaigns">{{T "Campaigns"}}</a>
|
||||||
</li>
|
</li>
|
||||||
<li><a href="/users">Users & Groups</a>
|
<li><a href="/users">{{T "Users & Groups"}}</a>
|
||||||
</li>
|
</li>
|
||||||
<li><a href="/templates">Email Templates</a>
|
<li><a href="/templates">{{T "Email Templates"}}</a>
|
||||||
</li>
|
</li>
|
||||||
<li><a href="/landing_pages">Landing Pages</a>
|
<li><a href="/landing_pages">{{T "Landing Pages"}}</a>
|
||||||
</li>
|
</li>
|
||||||
<li><a href="/sending_profiles">Sending Profiles</a>
|
<li><a href="/sending_profiles">{{T "Sending Profiles"}}</a>
|
||||||
</li>
|
</li>
|
||||||
<li><a href="/settings">Settings</a>
|
<li><a href="/settings">{{T "Settings"}}</a>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
{{if .User}}
|
{{if .User}}
|
||||||
|
@ -67,7 +67,7 @@
|
||||||
</div>
|
</div>
|
||||||
{{else}}
|
{{else}}
|
||||||
<a href="/login">
|
<a href="/login">
|
||||||
<button type="button" class="btn btn-primary">Login</button>
|
<button type="button" class="btn btn-primary">{{T "Login"}}</button>
|
||||||
</a>
|
</a>
|
||||||
{{end}}
|
{{end}}
|
||||||
</li>
|
</li>
|
||||||
|
@ -79,6 +79,7 @@
|
||||||
<!-- Placed at the end of the document so the pages load faster -->
|
<!-- Placed at the end of the document so the pages load faster -->
|
||||||
<script src="/js/dist/vendor.min.js"></script>
|
<script src="/js/dist/vendor.min.js"></script>
|
||||||
<script src="/js/dist/app/gophish.min.js"></script>
|
<script src="/js/dist/app/gophish.min.js"></script>
|
||||||
|
<script src="/js/src/app/localization.support.js"></script>
|
||||||
{{template "scripts" .}}
|
{{template "scripts" .}}
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
|
|
|
@ -3,24 +3,24 @@
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-sm-3 col-md-2 sidebar">
|
<div class="col-sm-3 col-md-2 sidebar">
|
||||||
<ul class="nav nav-sidebar">
|
<ul class="nav nav-sidebar">
|
||||||
<li><a href="/">Dashboard</a>
|
<li><a href="/">{{T "Dashboard"}}</a>
|
||||||
</li>
|
</li>
|
||||||
<li class="active"><a href="/campaigns">Campaigns</a>
|
<li class="active"><a href="/campaigns">{{T "Campaigns"}}</a>
|
||||||
</li>
|
</li>
|
||||||
<li><a href="/users">Users & Groups</a>
|
<li><a href="/users">{{T "Users & Groups"}}</a>
|
||||||
</li>
|
</li>
|
||||||
<li><a href="/templates">Email Templates</a>
|
<li><a href="/templates">{{T "Email Templates"}}</a>
|
||||||
</li>
|
</li>
|
||||||
<li><a href="/landing_pages">Landing Pages</a>
|
<li><a href="/landing_pages">{{T "Landing Pages"}}</a>
|
||||||
</li>
|
</li>
|
||||||
<li><a href="/sending_profiles">Sending Profiles</a>
|
<li><a href="/sending_profiles">{{T "Sending Profiles"}}</a>
|
||||||
</li>
|
</li>
|
||||||
<li><a href="/settings">Settings</a>
|
<li><a href="/settings">{{T "Settings"}}</a>
|
||||||
</li>
|
</li>
|
||||||
<li><hr></li>
|
<li><hr></li>
|
||||||
<li><a href="https://gophish.gitbooks.io/user-guide/content/">User Guide</a>
|
<li><a href="https://gophish.gitbooks.io/user-guide/content/">{{T "User Guide"}}</a>
|
||||||
</li>
|
</li>
|
||||||
<li><a href="/api/">API Documentation</a>
|
<li><a href="/api/">{{T "API Documentation"}}</a>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
@ -32,36 +32,36 @@
|
||||||
</div>
|
</div>
|
||||||
<div style="display:none;" id="campaignResults">
|
<div style="display:none;" id="campaignResults">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<h1 class="page-header" id="page-title">Results for campaign.name</h1>
|
<h1 class="page-header" id="page-title">{{T "Results for campaign.name"}}</h1>
|
||||||
</div>
|
</div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<a href="/campaigns" class="btn btn-default">
|
<a href="/campaigns" class="btn btn-default">
|
||||||
<i class="fa fa-arrow-circle-o-left fa-lg"></i> Back
|
<i class="fa fa-arrow-circle-o-left fa-lg"></i> {{T "Back"}}
|
||||||
</a>
|
</a>
|
||||||
<div class="btn-group">
|
<div class="btn-group">
|
||||||
<button type="button" id="exportButton" class="btn btn-primary dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="true">
|
<button type="button" id="exportButton" class="btn btn-primary dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="true">
|
||||||
<i class="fa fa-file-excel-o"></i> Export CSV
|
<i class="fa fa-file-excel-o"></i> {{T "Export CSV"}}
|
||||||
<i class="fa fa-caret-down"></i>
|
<i class="fa fa-caret-down"></i>
|
||||||
</button>
|
</button>
|
||||||
<ul class="dropdown-menu" aria-labelledby="exportButton">
|
<ul class="dropdown-menu" aria-labelledby="exportButton">
|
||||||
<li><a href="#" onclick="exportAsCSV('results')">Results</a></li>
|
<li><a href="#" onclick="exportAsCSV('results')">{{T "Results"}}</a></li>
|
||||||
<li><a href="#" onclick="exportAsCSV('events')">Raw Events</a></li>
|
<li><a href="#" onclick="exportAsCSV('events')">{{T "Raw Events"}}</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
<button id="complete_button" type="button" class="btn btn-blue" data-toggle="tooltip" onclick="completeCampaign()">
|
<button id="complete_button" type="button" class="btn btn-blue" data-toggle="tooltip" onclick="completeCampaign()">
|
||||||
<i class="fa fa-flag-checkered"></i> Complete
|
<i class="fa fa-flag-checkered"></i> {{T "Complete"}}
|
||||||
</button>
|
</button>
|
||||||
<button type="button" class="btn btn-danger" data-toggle="tooltip" onclick="deleteCampaign()">
|
<button type="button" class="btn btn-danger" data-toggle="tooltip" onclick="deleteCampaign()">
|
||||||
<i class="fa fa-trash-o fa-lg"></i> Delete
|
<i class="fa fa-trash-o fa-lg"></i> {{T "Delete"}}
|
||||||
</button>
|
</button>
|
||||||
<span id="refresh_message">
|
<span id="refresh_message">
|
||||||
<i class="fa fa-spin fa-spinner"></i> Refreshing
|
<i class="fa fa-spin fa-spinner"></i> {{T "Refreshing"}}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<br />
|
<br />
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<ul class="nav nav-tabs" role="tablist">
|
<ul class="nav nav-tabs" role="tablist">
|
||||||
<li class="active"><a href="#overview" aria-controls="home" role="tab" data-toggle="tab">Overview</a></li>
|
<li class="active"><a href="#overview" aria-controls="home" role="tab" data-toggle="tab">{{T "Overview"}}</a></li>
|
||||||
<!--<li><a href="#plugins" aria-controls="profile" role="tab" data-toggle="tab">Plugins</a></li>
|
<!--<li><a href="#plugins" aria-controls="profile" role="tab" data-toggle="tab">Plugins</a></li>
|
||||||
<li><a href="#demographics" aria-controls="settings" role="tab" data-toggle="tab">Demographics</a></li>-->
|
<li><a href="#demographics" aria-controls="settings" role="tab" data-toggle="tab">Demographics</a></li>-->
|
||||||
</ul>
|
</ul>
|
||||||
|
@ -70,12 +70,12 @@
|
||||||
<br/>
|
<br/>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-lg-6 col-md-6 col-sm-12 col-xs-12">
|
<div class="col-lg-6 col-md-6 col-sm-12 col-xs-12">
|
||||||
<p style="text-align:center;">Campaign Timeline</p>
|
<p style="text-align:center;">{{T "Campaign Timeline"}}</p>
|
||||||
<br/>
|
<br/>
|
||||||
<div id="timeline_chart"></div>
|
<div id="timeline_chart"></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-lg-6 col-md-6 col-sm-12 col-xs-12">
|
<div class="col-lg-6 col-md-6 col-sm-12 col-xs-12">
|
||||||
<p style="text-align:center;">Email Status</p>
|
<p style="text-align:center;">{{T "Email Status"}}</p>
|
||||||
<div id="email_chart" class="col-lg-7 col-md-7"></div>
|
<div id="email_chart" class="col-lg-7 col-md-7"></div>
|
||||||
<div class="col-lg-5 col-md-5">
|
<div class="col-lg-5 col-md-5">
|
||||||
<ul id="email_chart_legend" class="chartist-legend">
|
<ul id="email_chart_legend" class="chartist-legend">
|
||||||
|
@ -85,7 +85,7 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-md-6">
|
<div class="col-md-6">
|
||||||
<p style="text-align:center;">Targets Map</p>
|
<p style="text-align:center;">{{T "Targets Map"}}</p>
|
||||||
<div id="resultsMap"></div>
|
<div id="resultsMap"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -99,17 +99,17 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<h2>Details</h2>
|
<h2>{{T "Details"}}</h2>
|
||||||
<table id="resultsTable" class="table">
|
<table id="resultsTable" class="table">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th>Result ID</th>
|
<th>{{T "Result ID"}}</th>
|
||||||
<th class="no-sort"></th>
|
<th class="no-sort"></th>
|
||||||
<th>First Name</th>
|
<th>{{T "First Name"}}</th>
|
||||||
<th>Last Name</th>
|
<th>{{T "Last Name"}}</th>
|
||||||
<th>Email</th>
|
<th>{{T "Email"}}</th>
|
||||||
<th>Position</th>
|
<th>{{T "Position"}}</th>
|
||||||
<th>Status</th>
|
<th>{{T "Status"}}</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
|
|
|
@ -3,24 +3,24 @@
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-sm-3 col-md-2 sidebar">
|
<div class="col-sm-3 col-md-2 sidebar">
|
||||||
<ul class="nav nav-sidebar">
|
<ul class="nav nav-sidebar">
|
||||||
<li><a href="/">Dashboard</a>
|
<li><a href="/">{{T "Dashboard"}}</a>
|
||||||
</li>
|
</li>
|
||||||
<li class="active"><a href="/campaigns">Campaigns</a>
|
<li class="active"><a href="/campaigns">{{T "Campaigns"}}</a>
|
||||||
</li>
|
</li>
|
||||||
<li><a href="/users">Users & Groups</a>
|
<li><a href="/users">{{T "Users & Groups"}}</a>
|
||||||
</li>
|
</li>
|
||||||
<li><a href="/templates">Email Templates</a>
|
<li><a href="/templates">{{T "Email Templates"}}</a>
|
||||||
</li>
|
</li>
|
||||||
<li><a href="/landing_pages">Landing Pages</a>
|
<li><a href="/landing_pages">{{T "Landing Pages"}}</a>
|
||||||
</li>
|
</li>
|
||||||
<li><a href="/sending_profiles">Sending Profiles</a>
|
<li><a href="/sending_profiles">{{T "Sending Profiles"}}</a>
|
||||||
</li>
|
</li>
|
||||||
<li><a href="/settings">Settings</a>
|
<li><a href="/settings">{{T "Settings"}}</a>
|
||||||
</li>
|
</li>
|
||||||
<li><hr></li>
|
<li><hr></li>
|
||||||
<li><a href="https://gophish.gitbooks.io/user-guide/content/">User Guide</a>
|
<li><a href="https://gophish.gitbooks.io/user-guide/content/">{{T "User Guide"}}</a>
|
||||||
</li>
|
</li>
|
||||||
<li><a href="/api/">API Documentation</a>
|
<li><a href="/api/">{{T "API Documentation"}}</a>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
@ -29,12 +29,12 @@
|
||||||
<div class="col-sm-9 col-sm-offset-3 col-md-10 col-md-offset-2 main">
|
<div class="col-sm-9 col-sm-offset-3 col-md-10 col-md-offset-2 main">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<h1 class="page-header">
|
<h1 class="page-header">
|
||||||
Campaigns
|
{{T "Campaigns"}}
|
||||||
</h1>
|
</h1>
|
||||||
</div>
|
</div>
|
||||||
<div id="flashes" class="row"></div>
|
<div id="flashes" class="row"></div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<button type="button" class="btn btn-primary" data-toggle="modal" data-target="#modal" onclick="edit('new')"><i class="fa fa-plus"></i> New Campaign</button>
|
<button type="button" class="btn btn-primary" data-toggle="modal" data-target="#modal" onclick="edit('new')"><i class="fa fa-plus"></i> {{T "New Campaign"}}</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="loading">
|
<div id="loading">
|
||||||
|
@ -42,16 +42,16 @@
|
||||||
</div>
|
</div>
|
||||||
<div id="emptyMessage" class="row" style="display:none;">
|
<div id="emptyMessage" class="row" style="display:none;">
|
||||||
<div class="alert alert-info">
|
<div class="alert alert-info">
|
||||||
No campaigns created yet. Let's create one!
|
{{T "No campaigns created yet. Let's create one!"}}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<table id="campaignTable" class="table" style="display:none;">
|
<table id="campaignTable" class="table" style="display:none;">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th class="col-md-3">Name</th>
|
<th class="col-md-3">{{T "Name"}}</th>
|
||||||
<th class="col-md-4">Created Date</th>
|
<th class="col-md-4">{{T "Created Date"}}</th>
|
||||||
<th class="col-md-2">Status</th>
|
<th class="col-md-2">{{T "Status"}}</th>
|
||||||
<th class="col-md-3 no-sort"></th>
|
<th class="col-md-3 no-sort"></th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
|
@ -66,41 +66,41 @@
|
||||||
<div class="modal-content">
|
<div class="modal-content">
|
||||||
<div class="modal-header">
|
<div class="modal-header">
|
||||||
<button type="button" class="close" data-dismiss="modal" aria-label="Close" onclick="dismiss()"><span aria-hidden="true">×</span></button>
|
<button type="button" class="close" data-dismiss="modal" aria-label="Close" onclick="dismiss()"><span aria-hidden="true">×</span></button>
|
||||||
<h4 class="modal-title" id="campaignModalLabel">New Campaign</h4>
|
<h4 class="modal-title" id="campaignModalLabel">{{T "New Campaign"}}</h4>
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-body" id="modal_body">
|
<div class="modal-body" id="modal_body">
|
||||||
<div class="row" id="modal.flashes"></div>
|
<div class="row" id="modal.flashes"></div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="name">Name:</label>
|
<label for="name">{{T "Name"}}:</label>
|
||||||
<input type="text" class="form-control" id="name" placeholder="Campaign name" autofocus>
|
<input type="text" class="form-control" id="name" placeholder="{{T "Campaign name"}}" autofocus>
|
||||||
<label class="control-label" for="template">Email Template:</label>
|
<label class="control-label" for="template">{{T "Email Template"}}:</label>
|
||||||
<select class="form-control" placeholder="Template Name" id="template"/>
|
<select class="form-control" placeholder="{{T "Template Name"}}" id="template"/>
|
||||||
<option></option>
|
<option></option>
|
||||||
</select>
|
</select>
|
||||||
<label class="control-label" for="page">Landing Page:</label>
|
<label class="control-label" for="page">{{T "Landing Page"}}:</label>
|
||||||
<select class="form-control" placeholder="Landing Page" id="page"/>
|
<select class="form-control" placeholder="Landing Page" id="page"/>
|
||||||
<option></option>
|
<option></option>
|
||||||
</select>
|
</select>
|
||||||
<label class="control-label" for="url">URL: <i class="fa fa-question-circle" data-toggle="tooltip" data-placement="right" title="Location of gophish listener (must be reachable by targets!)"></i></label>
|
<label class="control-label" for="url">{{T "URL"}}: <i class="fa fa-question-circle" data-toggle="tooltip" data-placement="right" title="{{T "Location of gophish listener (must be reachable by targets!)"}}"></i></label>
|
||||||
<input type="text" class="form-control" placeholder="http://192.168.1.1" id="url"/>
|
<input type="text" class="form-control" placeholder="http://192.168.1.1" id="url"/>
|
||||||
<label class="control-label" for="url">Schedule: </label>
|
<label class="control-label" for="url">{{T "Schedule"}}: </label>
|
||||||
<input type="text" class="form-control" id="launch_date"/>
|
<input type="text" class="form-control" id="launch_date"/>
|
||||||
<label class="control-label" for="profile">Sending Profile:</label>
|
<label class="control-label" for="profile">{{T "Sending Profile"}}:</label>
|
||||||
<div class="input-group">
|
<div class="input-group">
|
||||||
<select class="form-control" placeholder="Sending Profile" id="profile"/>
|
<select class="form-control" placeholder="{{T "Sending Profile"}}" id="profile"/>
|
||||||
<option></option>
|
<option></option>
|
||||||
</select>
|
</select>
|
||||||
<span class="input-group-btn">
|
<span class="input-group-btn">
|
||||||
<button type="button" data-toggle="modal" data-target="#sendTestEmailModal" class="btn btn-primary button"><i class="fa fa-envelope"></i> Send Test Email</button>
|
<button type="button" data-toggle="modal" data-target="#sendTestEmailModal" class="btn btn-primary button"><i class="fa fa-envelope"></i> {{T "Send Test Email"}}</button>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<label class="control-label" for="users">Groups:</label>
|
<label class="control-label" for="users">{{T "Groups"}}:</label>
|
||||||
<select class="form-control" id="users" multiple="multiple"></select>
|
<select class="form-control" id="users" multiple="multiple"></select>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-footer">
|
<div class="modal-footer">
|
||||||
<button type="button" class="btn btn-default" data-dismiss="modal" onclick="dismiss()">Close</button>
|
<button type="button" class="btn btn-default" data-dismiss="modal" onclick="dismiss()">{{T "Close"}}</button>
|
||||||
<button type="button" id="launchButton" class="btn btn-primary" onclick="launch()"><i class="fa fa-rocket"></i> Launch Campaign</button>
|
<button type="button" id="launchButton" class="btn btn-primary" onclick="launch()"><i class="fa fa-rocket"></i> {{T "Launch Campaign"}}</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -112,32 +112,32 @@
|
||||||
<!-- New Email Modal -->
|
<!-- New Email Modal -->
|
||||||
<div class="modal-header">
|
<div class="modal-header">
|
||||||
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
|
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
|
||||||
<h4 class="modal-title" id="sendTestEmailModalTitle">Send Test Email</h4>
|
<h4 class="modal-title" id="sendTestEmailModalTitle">{{T "Send Test Email"}}</h4>
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-body">
|
<div class="modal-body">
|
||||||
<div class="row" id="sendTestEmailModal.flashes"></div>
|
<div class="row" id="sendTestEmailModal.flashes"></div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-sm-12">
|
<div class="col-sm-12">
|
||||||
<label class="control-label" for="to">Send Test Email to:</label>
|
<label class="control-label" for="to">{{T "Send Test Email to"}}:</label>
|
||||||
</div>
|
</div>
|
||||||
<br>
|
<br>
|
||||||
<div class="col-sm-2">
|
<div class="col-sm-2">
|
||||||
<input type="text" class="form-control" placeholder="First Name" name="to_first_name">
|
<input type="text" class="form-control" placeholder="{{T "First Name"}}" name="to_first_name">
|
||||||
</div>
|
</div>
|
||||||
<div class="col-sm-2">
|
<div class="col-sm-2">
|
||||||
<input type="text" class="form-control" placeholder="Last Name" name="to_last_name">
|
<input type="text" class="form-control" placeholder="{{T "Last Name"}}" name="to_last_name">
|
||||||
</div>
|
</div>
|
||||||
<div class="col-sm-4">
|
<div class="col-sm-4">
|
||||||
<input type="email" class="form-control" placeholder="Email" name="to_email" required>
|
<input type="email" class="form-control" placeholder="{{T "Email"}}" name="to_email" required>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-sm-4">
|
<div class="col-sm-4">
|
||||||
<input type="text" class="form-control" placeholder="Position" name="to_position">
|
<input type="text" class="form-control" placeholder="{{T "Position"}}" name="to_position">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-footer">
|
<div class="modal-footer">
|
||||||
<button type="button" data-dismiss="modal" class="btn btn-default">Cancel</button>
|
<button type="button" data-dismiss="modal" class="btn btn-default">{{T "Cancel"}}</button>
|
||||||
<button type="button" class="btn btn-primary" id="sendTestModalSubmit" onclick="sendTestEmail()"><i class="fa fa-envelope"></i> Send</button>
|
<button type="button" class="btn btn-primary" id="sendTestModalSubmit" onclick="sendTestEmail()"><i class="fa fa-envelope"></i> {{T "Send"}}</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -3,24 +3,24 @@
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-sm-3 col-md-2 sidebar">
|
<div class="col-sm-3 col-md-2 sidebar">
|
||||||
<ul class="nav nav-sidebar">
|
<ul class="nav nav-sidebar">
|
||||||
<li class="active"><a href="#">Dashboard</a>
|
<li class="active"><a href="#">{{T "Dashboard"}}</a>
|
||||||
</li>
|
</li>
|
||||||
<li><a href="/campaigns">Campaigns</a>
|
<li><a href="/campaigns">{{T "Campaigns"}}</a>
|
||||||
</li>
|
</li>
|
||||||
<li><a href="/users">Users & Groups</a>
|
<li><a href="/users">{{T "Users & Groups"}}</a>
|
||||||
</li>
|
</li>
|
||||||
<li><a href="/templates">Email Templates</a>
|
<li><a href="/templates">{{T "Email Templates"}}</a>
|
||||||
</li>
|
</li>
|
||||||
<li><a href="/landing_pages">Landing Pages</a>
|
<li><a href="/landing_pages">{{T "Landing Pages"}}</a>
|
||||||
</li>
|
</li>
|
||||||
<li><a href="/sending_profiles">Sending Profiles</a>
|
<li><a href="/sending_profiles">{{T "Sending Profiles"}}</a>
|
||||||
</li>
|
</li>
|
||||||
<li><a href="/settings">Settings</a>
|
<li><a href="/settings">{{T "Settings"}}</a>
|
||||||
</li>
|
</li>
|
||||||
<li><hr></li>
|
<li><hr></li>
|
||||||
<li><a href="https://gophish.gitbooks.io/user-guide/content/">User Guide</a>
|
<li><a href="https://gophish.gitbooks.io/user-guide/content/">{{T "User Guide"}}</a>
|
||||||
</li>
|
</li>
|
||||||
<li><a href="/api/">API Documentation</a>
|
<li><a href="/api/">{{T "API Documentation"}}</a>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
@ -28,50 +28,50 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="col-sm-9 col-sm-offset-3 col-md-10 col-md-offset-2 main">
|
<div class="col-sm-9 col-sm-offset-3 col-md-10 col-md-offset-2 main">
|
||||||
<h1 class="page-header">
|
<h1 class="page-header">
|
||||||
Dashboard
|
{{T "Dashboard"}}
|
||||||
</h1>
|
</h1>
|
||||||
<div id="loading">
|
<div id="loading">
|
||||||
<i class="fa fa-spinner fa-spin fa-4x"></i>
|
<i class="fa fa-spinner fa-spin fa-4x"></i>
|
||||||
</div>
|
</div>
|
||||||
<div id="emptyMessage" class="row" style="display:none;">
|
<div id="emptyMessage" class="row" style="display:none;">
|
||||||
<div class="alert alert-info">
|
<div class="alert alert-info">
|
||||||
No campaigns created yet. Let's create one!
|
{{T "No campaigns created yet. Let's create one!"}}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div id="dashboard" style="display:none;">
|
<div id="dashboard" style="display:none;">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div id="overview_chart" class="col-lg-6 col-md-6 col-sm-12 col-xs-12">
|
<div id="overview_chart" class="col-lg-6 col-md-6 col-sm-12 col-xs-12">
|
||||||
<p style="text-align:center;">Phishing Success Overview</p>
|
<p style="text-align:center;">{{T "Phishing Success Overview"}}</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-lg-6 col-md-6 col-sm-12 col-xs-12">
|
<div class="col-lg-6 col-md-6 col-sm-12 col-xs-12">
|
||||||
<p style="text-align:center;">Average Phishing Results</p>
|
<p style="text-align:center;">{{T "Average Phishing Results"}}</p>
|
||||||
<div id="average_chart" class="col-lg-7 col-md-7"></div>
|
<div id="average_chart" class="col-lg-7 col-md-7"></div>
|
||||||
<div id="average_chart_legend" class="col-lg-5 col-md-5">
|
<div id="average_chart_legend" class="col-lg-5 col-md-5">
|
||||||
<ul class="chartist-legend">
|
<ul class="chartist-legend">
|
||||||
<li>
|
<li>
|
||||||
<span style="background-color:#f05b4f;"></span> Successful Phishes
|
<span style="background-color:#f05b4f;"></span> {{T "Successful Phishes"}}
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<span style="background-color:#1abc9c;"></span> Unsuccessful Phishes
|
<span style="background-color:#1abc9c;"></span> {{T "Unsuccessful Phishes"}}
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<h2>Recent Campaigns</h2>
|
<h2>{{T "Recent Campaigns"}}</h2>
|
||||||
</div>
|
</div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<a href="/campaigns"><button type="button" class="btn btn-primary">View All</button></a>
|
<a href="/campaigns"><button type="button" class="btn btn-primary">{{T "View All"}}</button></a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<table id="campaignTable" class="table">
|
<table id="campaignTable" class="table">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th>Name</th>
|
<th>{{T "Name"}}</th>
|
||||||
<th>Created Date</th>
|
<th>{{T "Created Date"}}</th>
|
||||||
<th>Status</th>
|
<th>{{T "Status"}}</th>
|
||||||
<th class="col-md-2 col-sm-2 no-sort"></th>
|
<th class="col-md-2 col-sm-2 no-sort"></th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
|
@ -83,5 +83,12 @@
|
||||||
</div>
|
</div>
|
||||||
{{end}}
|
{{end}}
|
||||||
{{define "scripts"}}
|
{{define "scripts"}}
|
||||||
<script src="/js/dist/app/dashboard.min.js"></script>
|
<script>
|
||||||
|
localizedDatas = {
|
||||||
|
"Delete": "Sil",
|
||||||
|
"View Results": "Sonuçları Göster",
|
||||||
|
"Delete Campaign": "Kampanyayı Sil"
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<script src="/js/src/app/dashboard.js"></script>
|
||||||
{{end}}
|
{{end}}
|
||||||
|
|
|
@ -3,24 +3,24 @@
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-sm-3 col-md-2 sidebar">
|
<div class="col-sm-3 col-md-2 sidebar">
|
||||||
<ul class="nav nav-sidebar">
|
<ul class="nav nav-sidebar">
|
||||||
<li><a href="/">Dashboard</a>
|
<li><a href="/">{{T "Dashboard"}}</a>
|
||||||
</li>
|
</li>
|
||||||
<li><a href="/campaigns">Campaigns</a>
|
<li><a href="/campaigns">{{T "Campaigns"}}</a>
|
||||||
</li>
|
</li>
|
||||||
<li><a href="/users">Users & Groups</a>
|
<li><a href="/users">{{T "Users & Groups"}}</a>
|
||||||
</li>
|
</li>
|
||||||
<li><a href="/templates">Email Templates</a>
|
<li><a href="/templates">{{T "Email Templates"}}</a>
|
||||||
</li>
|
</li>
|
||||||
<li class="active"><a href="/landing_pages">Landing Pages</a>
|
<li class="active"><a href="/landing_pages">{{T "Landing Pages"}}</a>
|
||||||
</li>
|
</li>
|
||||||
<li><a href="/sending_profiles">Sending Profiles</a>
|
<li><a href="/sending_profiles">{{T "Sending Profiles"}}</a>
|
||||||
</li>
|
</li>
|
||||||
<li><a href="/settings">Settings</a>
|
<li><a href="/settings">{{T "Settings"}}</a>
|
||||||
</li>
|
</li>
|
||||||
<li><hr></li>
|
<li><hr></li>
|
||||||
<li><a href="https://gophish.gitbooks.io/user-guide/content/">User Guide</a>
|
<li><a href="https://gophish.gitbooks.io/user-guide/content/">{{T "User Guide"}}</a>
|
||||||
</li>
|
</li>
|
||||||
<li><a href="/api/">API Documentation</a>
|
<li><a href="/api/">{{T "API Documentation"}}</a>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
@ -28,11 +28,11 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="col-sm-9 col-sm-offset-3 col-md-10 col-md-offset-2 main">
|
<div class="col-sm-9 col-sm-offset-3 col-md-10 col-md-offset-2 main">
|
||||||
<h1 class="page-header">
|
<h1 class="page-header">
|
||||||
Landing Pages
|
{{T "Landing Pages"}}
|
||||||
</h1>
|
</h1>
|
||||||
<div id="flashes" class="row"></div>
|
<div id="flashes" class="row"></div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<button type="button" class="btn btn-primary" onclick="edit(-1)" data-toggle="modal" data-target="#modal"><i class="fa fa-plus"></i> New Page</button>
|
<button type="button" class="btn btn-primary" onclick="edit(-1)" data-toggle="modal" data-target="#modal"><i class="fa fa-plus"></i> {{T "New Page"}}</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="loading">
|
<div id="loading">
|
||||||
|
@ -40,15 +40,15 @@
|
||||||
</div>
|
</div>
|
||||||
<div id="emptyMessage" class="row" style="display:none;">
|
<div id="emptyMessage" class="row" style="display:none;">
|
||||||
<div class="alert alert-info">
|
<div class="alert alert-info">
|
||||||
No pages created yet. Let's create one!
|
{{T "No pages created yet. Let's create one!"}}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<table id="pagesTable" class="table" style="display:none;">
|
<table id="pagesTable" class="table" style="display:none;">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th>Name</th>
|
<th>{{T "Name"}}</th>
|
||||||
<th>Last Modified Date</th>
|
<th>{{T "Last Modified Date"}}</th>
|
||||||
<th class="col-md-2 no-sort"></th>
|
<th class="col-md-2 no-sort"></th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
|
@ -64,16 +64,16 @@
|
||||||
<!-- New Template Modal -->
|
<!-- New Template Modal -->
|
||||||
<div class="modal-header">
|
<div class="modal-header">
|
||||||
<button type="button" class="close" data-dismiss="modal" aria-label="Close" onclick="dismiss()"><span aria-hidden="true">×</span></button>
|
<button type="button" class="close" data-dismiss="modal" aria-label="Close" onclick="dismiss()"><span aria-hidden="true">×</span></button>
|
||||||
<h4 class="modal-title" id="modalLabel">New Landing Page</h4>
|
<h4 class="modal-title" id="modalLabel">{{T "New Landing Page"}}</h4>
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-body">
|
<div class="modal-body">
|
||||||
<div class="row" id="modal.flashes"></div>
|
<div class="row" id="modal.flashes"></div>
|
||||||
<label class="control-label" for="name">Name:</label>
|
<label class="control-label" for="name">{{T "Name"}}:</label>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<input type="text" class="form-control" placeholder="Page name" id="name" autofocus/>
|
<input type="text" class="form-control" placeholder="{{T "Page name"}}" id="name" autofocus/>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<button class="btn btn-danger" data-toggle="modal" data-target="#importSiteModal"><i class="fa fa-globe"></i> Import Site</button>
|
<button class="btn btn-danger" data-toggle="modal" data-target="#importSiteModal"><i class="fa fa-globe"></i> {{T "Import Site"}}</button>
|
||||||
</div>
|
</div>
|
||||||
<!-- Nav tabs -->
|
<!-- Nav tabs -->
|
||||||
<ul class="nav nav-tabs" role="tablist">
|
<ul class="nav nav-tabs" role="tablist">
|
||||||
|
@ -87,25 +87,25 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="checkbox checkbox-primary">
|
<div class="checkbox checkbox-primary">
|
||||||
<input id="capture_credentials_checkbox" type="checkbox">
|
<input id="capture_credentials_checkbox" type="checkbox">
|
||||||
<label for="capture_credentials_checkbox">Capture Submitted Data <i class="fa fa-question-circle" data-toggle="tooltip" data-placement="right" title="If the landing page contains a form, submitted input (except passwords!) will be captured."></i></label>
|
<label for="capture_credentials_checkbox">{{T "Capture Submitted Data"}} <i class="fa fa-question-circle" data-toggle="tooltip" data-placement="right" title="{{T "If the landing page contains a form, submitted input (except passwords!) will be captured."}}"></i></label>
|
||||||
</div>
|
</div>
|
||||||
<div class="checkbox checkbox-primary" id="capture_passwords">
|
<div class="checkbox checkbox-primary" id="capture_passwords">
|
||||||
<input id="capture_passwords_checkbox" type="checkbox">
|
<input id="capture_passwords_checkbox" type="checkbox">
|
||||||
<label for="capture_passwords_checkbox">Capture Passwords</label>
|
<label for="capture_passwords_checkbox">{{T "Capture Passwords"}}</label>
|
||||||
<div class="alert alert-warning">
|
<div class="alert alert-warning">
|
||||||
<i class="fa fa-exclamation-circle"></i> <b>Warning:</b> Credentials are currently <b>not encrypted</b>. This means that captured passwords are stored in the database as cleartext. Be careful with this!
|
<i class="fa fa-exclamation-circle"></i> {{T "<b>Warning:</b> Credentials are currently <b>not encrypted</b>. This means that captured passwords are stored in the database as cleartext. Be careful with this!"}}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div id="redirect_url">
|
<div id="redirect_url">
|
||||||
<label class="control-label" for="redirect_url_input">Redirect to: <i class="fa fa-question-circle" data-toggle="tooltip" data-placement="right" title="This option lets you redirect the user to a page after credentials are submitted."></i></label>
|
<label class="control-label" for="redirect_url_input">{{T "Redirect to"}}: <i class="fa fa-question-circle" data-toggle="tooltip" data-placement="right" title="{{T "This option lets you redirect the user to a page after credentials are submitted."}}"></i></label>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<input id="redirect_url_input" class="form-control" placeholder="http://example.com"/>
|
<input id="redirect_url_input" class="form-control" placeholder="{{T "http://example.com"}}"/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-footer">
|
<div class="modal-footer">
|
||||||
<button type="button" data-dismiss="modal" class="btn btn-default" onclick="dismiss()">Cancel</button>
|
<button type="button" data-dismiss="modal" class="btn btn-default" onclick="dismiss()">{{T "Cancel"}}</button>
|
||||||
<button type="button" class="btn btn-primary" id="modalSubmit">Save Page</button>
|
<button type="button" class="btn btn-primary" id="modalSubmit">{{T "Save Page"}}</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -117,18 +117,18 @@
|
||||||
<!-- New Template Modal -->
|
<!-- New Template Modal -->
|
||||||
<div class="modal-header">
|
<div class="modal-header">
|
||||||
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
|
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
|
||||||
<h4 class="modal-title" id="importSiteModalLabel">Import Site</h4>
|
<h4 class="modal-title" id="importSiteModalLabel">{{T "Import Site"}}</h4>
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-body">
|
<div class="modal-body">
|
||||||
<div class="row" id="modal.flashes"></div>
|
<div class="row" id="modal.flashes"></div>
|
||||||
<label class="control-label" for="url">URL:</label>
|
<label class="control-label" for="url">{{T "URL"}}:</label>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<input type="text" class="form-control" placeholder="http://google.com" id="url" autofocus/>
|
<input type="text" class="form-control" placeholder="{{T "http://google.com"}}" id="url" autofocus/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-footer">
|
<div class="modal-footer">
|
||||||
<button type="button" data-dismiss="modal" class="btn btn-default">Cancel</button>
|
<button type="button" data-dismiss="modal" class="btn btn-default">{{T "Cancel"}}</button>
|
||||||
<button type="button" class="btn btn-primary" id="modalSubmit" onclick="importSite()">Import</button>
|
<button type="button" class="btn btn-primary" id="modalSubmit" onclick="importSite()">{{T "Import"}}</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -21,7 +21,7 @@
|
||||||
<div class="container-fluid">
|
<div class="container-fluid">
|
||||||
<div class="navbar-header">
|
<div class="navbar-header">
|
||||||
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
|
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
|
||||||
<span class="sr-only">Toggle navigation</span>
|
<span class="sr-only">{{T "Toggle navigation"}}</span>
|
||||||
<span class="icon-bar"></span>
|
<span class="icon-bar"></span>
|
||||||
<span class="icon-bar"></span>
|
<span class="icon-bar"></span>
|
||||||
<span class="icon-bar"></span>
|
<span class="icon-bar"></span>
|
||||||
|
@ -33,7 +33,7 @@
|
||||||
<ul class="nav navbar-nav navbar-right">
|
<ul class="nav navbar-nav navbar-right">
|
||||||
<li>
|
<li>
|
||||||
<a id="login-button" href="/login">
|
<a id="login-button" href="/login">
|
||||||
<button type="button" class="btn btn-primary">Login</button>
|
<button type="button" class="btn btn-primary">{{T "Login"}}</button>
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
@ -43,12 +43,12 @@
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<form class="form-signin" action="/login" method="POST">
|
<form class="form-signin" action="/login" method="POST">
|
||||||
<img id="logo" src="/images/logo_purple.png" />
|
<img id="logo" src="/images/logo_purple.png" />
|
||||||
<h2 class="form-signin-heading">Please sign in</h2>
|
<h2 class="form-signin-heading">{{T "Please sign in"}}</h2>
|
||||||
{{template "flashes" .Flashes}}
|
{{template "flashes" .Flashes}}
|
||||||
<input type="text" name="username" class="form-control top-input" placeholder="Username" required autofocus>
|
<input type="text" name="username" class="form-control top-input" placeholder="{{T "Username"}}" required autofocus>
|
||||||
<input type="password" name="password" class="form-control bottom-input" placeholder="Password" autocomplete="off" required>
|
<input type="password" name="password" class="form-control bottom-input" placeholder="{{T "Password"}}" autocomplete="off" required>
|
||||||
<input type="hidden" name="csrf_token" value="{{.Token}}"/>
|
<input type="hidden" name="csrf_token" value="{{.Token}}"/>
|
||||||
<button class="btn btn-lg btn-primary btn-block" type="submit">Sign in</button>
|
<button class="btn btn-lg btn-primary btn-block" type="submit">{{T "Sign in"}}</button>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
<!-- Placed at the end of the document so the pages load faster -->
|
<!-- Placed at the end of the document so the pages load faster -->
|
||||||
|
|
|
@ -21,7 +21,7 @@
|
||||||
<div class="container-fluid">
|
<div class="container-fluid">
|
||||||
<div class="navbar-header">
|
<div class="navbar-header">
|
||||||
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
|
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
|
||||||
<span class="sr-only">Toggle navigation</span>
|
<span class="sr-only">{{T "Toggle navigation"}}</span>
|
||||||
<span class="icon-bar"></span>
|
<span class="icon-bar"></span>
|
||||||
<span class="icon-bar"></span>
|
<span class="icon-bar"></span>
|
||||||
<span class="icon-bar"></span>
|
<span class="icon-bar"></span>
|
||||||
|
@ -33,7 +33,7 @@
|
||||||
<ul class="nav navbar-nav navbar-right">
|
<ul class="nav navbar-nav navbar-right">
|
||||||
<li>
|
<li>
|
||||||
<a id="login-button" href="/login">
|
<a id="login-button" href="/login">
|
||||||
<button type="button" class="btn btn-primary">Login</button>
|
<button type="button" class="btn btn-primary">{{T "Login"}}</button>
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
@ -43,13 +43,13 @@
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<form class="form-signin" action="/register" method="POST">
|
<form class="form-signin" action="/register" method="POST">
|
||||||
<img id="logo" src="/images/logo_purple.png" />
|
<img id="logo" src="/images/logo_purple.png" />
|
||||||
<h2 class="form-signin-heading">Please register below</h2>
|
<h2 class="form-signin-heading">{{T "Please register below"}}</h2>
|
||||||
{{template "flashes" .Flashes}}
|
{{template "flashes" .Flashes}}
|
||||||
<input type="text" name="username" class="form-control top-input" placeholder="Username" required autofocus/>
|
<input type="text" name="username" class="form-control top-input" placeholder="{{T "Username"}}" required autofocus/>
|
||||||
<input type="password" name="password" class="form-control middle-input" placeholder="Password" autocomplete="off" required/>
|
<input type="password" name="password" class="form-control middle-input" placeholder="{{T "Password"}}" autocomplete="off" required/>
|
||||||
<input type="password" name="confirm_password" class="form-control bottom-input" placeholder="Confirm Password" autocomplete="off" required/>
|
<input type="password" name="confirm_password" class="form-control bottom-input" placeholder="Confirm Password" autocomplete="off" required/>
|
||||||
<input type="hidden" name="csrf_token" value="{{.Token}}"/>
|
<input type="hidden" name="csrf_token" value="{{.Token}}"/>
|
||||||
<button class="btn btn-lg btn-primary btn-block" type="submit">Register</button>
|
<button class="btn btn-lg btn-primary btn-block" type="submit">{{T "Register"}}</button>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
<!-- Placed at the end of the document so the pages load faster -->
|
<!-- Placed at the end of the document so the pages load faster -->
|
||||||
|
|
|
@ -3,24 +3,24 @@
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-sm-3 col-md-2 sidebar">
|
<div class="col-sm-3 col-md-2 sidebar">
|
||||||
<ul class="nav nav-sidebar">
|
<ul class="nav nav-sidebar">
|
||||||
<li><a href="/">Dashboard</a>
|
<li><a href="/">{{T "Dashboard"}}</a>
|
||||||
</li>
|
</li>
|
||||||
<li><a href="/campaigns">Campaigns</a>
|
<li><a href="/campaigns">{{T "Campaigns"}}</a>
|
||||||
</li>
|
</li>
|
||||||
<li><a href="/users">Users & Groups</a>
|
<li><a href="/users">{{T "Users & Groups"}}</a>
|
||||||
</li>
|
</li>
|
||||||
<li><a href="/templates">Email Templates</a>
|
<li><a href="/templates">{{T "Email Templates"}}</a>
|
||||||
</li>
|
</li>
|
||||||
<li><a href="/landing_pages">Landing Pages</a>
|
<li><a href="/landing_pages">{{T "Landing Pages"}}</a>
|
||||||
</li>
|
</li>
|
||||||
<li class="active"><a href="/sending_profiles">Sending Profiles</a>
|
<li class="active"><a href="/sending_profiles">{{T "Sending Profiles"}}</a>
|
||||||
</li>
|
</li>
|
||||||
<li><a href="/settings">Settings</a>
|
<li><a href="/settings">{{T "Settings"}}</a>
|
||||||
</li>
|
</li>
|
||||||
<li><hr></li>
|
<li><hr></li>
|
||||||
<li><a href="https://gophish.gitbooks.io/user-guide/content/">User Guide</a>
|
<li><a href="https://gophish.gitbooks.io/user-guide/content/">{{T "User Guide"}}</a>
|
||||||
</li>
|
</li>
|
||||||
<li><a href="/api/">API Documentation</a>
|
<li><a href="/api/">{{T "API Documentation"}}</a>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
@ -28,11 +28,11 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="col-sm-9 col-sm-offset-3 col-md-10 col-md-offset-2 main">
|
<div class="col-sm-9 col-sm-offset-3 col-md-10 col-md-offset-2 main">
|
||||||
<h1 class="page-header">
|
<h1 class="page-header">
|
||||||
Sending Profiles
|
{{T "Sending Profiles"}}
|
||||||
</h1>
|
</h1>
|
||||||
<div id="flashes" class="row"></div>
|
<div id="flashes" class="row"></div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<button type="button" class="btn btn-primary" onclick="edit(-1)" data-toggle="modal" data-target="#modal"><i class="fa fa-plus"></i> New Profile</button>
|
<button type="button" class="btn btn-primary" onclick="edit(-1)" data-toggle="modal" data-target="#modal"><i class="fa fa-plus"></i> {{T "New Profile"}}</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="loading">
|
<div id="loading">
|
||||||
|
@ -40,16 +40,16 @@
|
||||||
</div>
|
</div>
|
||||||
<div id="emptyMessage" class="row" style="display:none;">
|
<div id="emptyMessage" class="row" style="display:none;">
|
||||||
<div class="alert alert-info">
|
<div class="alert alert-info">
|
||||||
No profiles created yet. Let's create one!
|
{{T "No profiles created yet. Let's create one!"}}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<table id="profileTable" class="table" style="display:none;">
|
<table id="profileTable" class="table" style="display:none;">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th class="col-md-4">Name</th>
|
<th class="col-md-4">{{T "Name"}}</th>
|
||||||
<th>Interface Type</th>
|
<th>{{T "Interface Type"}}</th>
|
||||||
<th>Last Modified Date</th>
|
<th>{{T "Last Modified Date"}}</th>
|
||||||
<th class="col-md-2 no-sort"></th>
|
<th class="col-md-2 no-sort"></th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
|
@ -65,34 +65,34 @@
|
||||||
<!-- New Template Modal -->
|
<!-- New Template Modal -->
|
||||||
<div class="modal-header">
|
<div class="modal-header">
|
||||||
<button type="button" class="close" data-dismiss="modal" aria-label="Close" onclick="dismiss()"><span aria-hidden="true">×</span></button>
|
<button type="button" class="close" data-dismiss="modal" aria-label="Close" onclick="dismiss()"><span aria-hidden="true">×</span></button>
|
||||||
<h4 class="modal-title" id="profileModalLabel">New Sending Profile</h4>
|
<h4 class="modal-title" id="profileModalLabel">{{T "New Sending Profile"}}</h4>
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-body">
|
<div class="modal-body">
|
||||||
<div class="row" id="modal.flashes"></div>
|
<div class="row" id="modal.flashes"></div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label class="control-label" for="name">Name:</label>
|
<label class="control-label" for="name">{{T "Name"}}:</label>
|
||||||
<input type="text" class="form-control" placeholder="Profile name" id="name" autofocus/>
|
<input type="text" class="form-control" placeholder="Profile name" id="name" autofocus/>
|
||||||
<label class="control-label" for="interface_type">Interface Type:</label>
|
<label class="control-label" for="interface_type">{{T "Interface Type"}}:</label>
|
||||||
<input type="text" class="form-control" value="SMTP" id="interface_type" disabled/>
|
<input type="text" class="form-control" value="{{T "SMTP"}}" id="interface_type" disabled/>
|
||||||
<label class="control-label" for="from">From:</label>
|
<label class="control-label" for="from">{{T "From"}}:</label>
|
||||||
<input type="text" class="form-control" placeholder="First Last <test@example.com>" id="from" required/>
|
<input type="text" class="form-control" placeholder="{{T "First Last <test@example.com>"}}" id="from" required/>
|
||||||
<label class="control-label" for="host">Host:</label>
|
<label class="control-label" for="host">{{T "Host"}}:</label>
|
||||||
<input type="text" class="form-control" placeholder="smtp.example.com:25" id="host" required/>
|
<input type="text" class="form-control" placeholder="{{T "smtp.example.com:25"}}" id="host" required/>
|
||||||
<label class="control-label" for="username">Username:</label>
|
<label class="control-label" for="username">{{T "Username"}}:</label>
|
||||||
<input type="text" class="form-control" placeholder="Username" id="username"/>
|
<input type="text" class="form-control" placeholder="{{T "Username"}}" id="username"/>
|
||||||
<label class="control-label" for="password">Password:</label>
|
<label class="control-label" for="password">{{T "Password"}}:</label>
|
||||||
<input type="password" class="form-control" placeholder="Password" id="password"/>
|
<input type="password" class="form-control" placeholder="{{T "Password"}}" id="password"/>
|
||||||
<div class="checkbox checkbox-primary">
|
<div class="checkbox checkbox-primary">
|
||||||
<input id="ignore_cert_errors" type="checkbox" checked>
|
<input id="ignore_cert_errors" type="checkbox" checked>
|
||||||
<label for="ignore_cert_errors">Ignore Certificate Errors <i class="fa fa-question-circle" data-toggle="tooltip" data-placement="right" title="Ignore common certificate errors such as self-signed certs (exposes you to MiTM attacks - use carefully!)"></i></label>
|
<label for="ignore_cert_errors">{{T "Ignore Certificate Errors"}} <i class="fa fa-question-circle" data-toggle="tooltip" data-placement="right" title="{{T "Ignore common certificate errors such as self-signed certs (exposes you to MiTM attacks - use carefully!)"}}"></i></label>
|
||||||
</div>
|
</div>
|
||||||
<button type="button" data-toggle="modal" data-target="#sendTestEmailModal" class="btn btn-primary"><i class="fa fa-envelope"></i> Send Test Email</button>
|
<button type="button" data-toggle="modal" data-target="#sendTestEmailModal" class="btn btn-primary"><i class="fa fa-envelope"></i> {{T "Send Test Email"}}</button>
|
||||||
<!-- disable sendTestEmail functionality on sending profile page until update handling of /util/send_test_email -->
|
<!-- disable sendTestEmail functionality on sending profile page until update handling of /util/send_test_email -->
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-footer">
|
<div class="modal-footer">
|
||||||
<button type="button" data-dismiss="modal" class="btn btn-default" onclick="dismiss()">Cancel</button>
|
<button type="button" data-dismiss="modal" class="btn btn-default" onclick="dismiss()">{{T "Cancel"}}</button>
|
||||||
<button type="button" class="btn btn-primary" id="modalSubmit">Save Profile</button>
|
<button type="button" class="btn btn-primary" id="modalSubmit">{{T "Save Profile"}}</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -104,32 +104,32 @@
|
||||||
<!-- New Email Modal -->
|
<!-- New Email Modal -->
|
||||||
<div class="modal-header">
|
<div class="modal-header">
|
||||||
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
|
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
|
||||||
<h4 class="modal-title" id="sendTestEmailModalTitle">Send Test Email</h4>
|
<h4 class="modal-title" id="sendTestEmailModalTitle">{{T "Send Test Email"}}</h4>
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-body">
|
<div class="modal-body">
|
||||||
<div class="row" id="sendTestEmailModal.flashes"></div>
|
<div class="row" id="sendTestEmailModal.flashes"></div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-sm-12">
|
<div class="col-sm-12">
|
||||||
<label class="control-label" for="to">Send Test Email to:</label>
|
<label class="control-label" for="to">{{T "Send Test Email to"}}:</label>
|
||||||
</div>
|
</div>
|
||||||
<br>
|
<br>
|
||||||
<div class="col-sm-2">
|
<div class="col-sm-2">
|
||||||
<input type="text" class="form-control" placeholder="First Name" name="to_first_name">
|
<input type="text" class="form-control" placeholder="{{T "First Name"}}" name="to_first_name">
|
||||||
</div>
|
</div>
|
||||||
<div class="col-sm-2">
|
<div class="col-sm-2">
|
||||||
<input type="text" class="form-control" placeholder="Last Name" name="to_last_name">
|
<input type="text" class="form-control" placeholder="{{T "Last Name"}}" name="to_last_name">
|
||||||
</div>
|
</div>
|
||||||
<div class="col-sm-4">
|
<div class="col-sm-4">
|
||||||
<input type="email" class="form-control" placeholder="Email" name="to_email" required>
|
<input type="email" class="form-control" placeholder="{{T "Email"}}" name="to_email" required>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-sm-4">
|
<div class="col-sm-4">
|
||||||
<input type="text" class="form-control" placeholder="Position" name="to_position">
|
<input type="text" class="form-control" placeholder="{{T "Position"}}" name="to_position">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-footer">
|
<div class="modal-footer">
|
||||||
<button type="button" data-dismiss="modal" class="btn btn-default">Cancel</button>
|
<button type="button" data-dismiss="modal" class="btn btn-default">{{T "Cancel"}}</button>
|
||||||
<button type="button" class="btn btn-primary" id="sendTestModalSubmit" onclick="sendTestEmail()"><i class="fa fa-envelope"></i> Send</button>
|
<button type="button" class="btn btn-primary" id="sendTestModalSubmit" onclick="sendTestEmail()"><i class="fa fa-envelope"></i> {{T "Send"}}</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -3,24 +3,24 @@
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-sm-3 col-md-2 sidebar">
|
<div class="col-sm-3 col-md-2 sidebar">
|
||||||
<ul class="nav nav-sidebar">
|
<ul class="nav nav-sidebar">
|
||||||
<li><a href="/">Dashboard</a>
|
<li><a href="/">{{T "Dashboard"}}</a>
|
||||||
</li>
|
</li>
|
||||||
<li><a href="/campaigns">Campaigns</a>
|
<li><a href="/campaigns">{{T "Campaigns"}}</a>
|
||||||
</li>
|
</li>
|
||||||
<li><a href="/users">Users & Groups</a>
|
<li><a href="/users">{{T "Users & Groups"}}</a>
|
||||||
</li>
|
</li>
|
||||||
<li><a href="/templates">Email Templates</a>
|
<li><a href="/templates">{{T "Email Templates"}}</a>
|
||||||
</li>
|
</li>
|
||||||
<li><a href="/landing_pages">Landing Pages</a>
|
<li><a href="/landing_pages">{{T "Landing Pages"}}</a>
|
||||||
</li>
|
</li>
|
||||||
<li><a href="/sending_profiles">Sending Profiles</a>
|
<li><a href="/sending_profiles">{{T "Sending Profiles"}}</a>
|
||||||
</li>
|
</li>
|
||||||
<li class="active"><a href="/settings">Settings</a>
|
<li class="active"><a href="/settings">{{T "Settings"}}</a>
|
||||||
</li>
|
</li>
|
||||||
<li><hr></li>
|
<li><hr></li>
|
||||||
<li><a href="https://gophish.gitbooks.io/user-guide/content/">User Guide</a>
|
<li><a href="https://gophish.gitbooks.io/user-guide/content/">{{T "User Guide"}}</a>
|
||||||
</li>
|
</li>
|
||||||
<li><a href="/api/">API Documentation</a>
|
<li><a href="/api/">{{T "API Documentation"}}</a>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
@ -28,65 +28,65 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="col-sm-9 col-sm-offset-3 col-md-10 col-md-offset-2 main">
|
<div class="col-sm-9 col-sm-offset-3 col-md-10 col-md-offset-2 main">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<h1 class="page-header">Settings</h1>
|
<h1 class="page-header">{{T "Settings"}}</h1>
|
||||||
</div>
|
</div>
|
||||||
<div id="flashes" class="row"></div>
|
<div id="flashes" class="row"></div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<label class="col-sm-2 control-label form-label">Gophish version</label>
|
<label class="col-sm-2 control-label form-label">{{T "Gophish version"}}</label>
|
||||||
<div class="col-md-6">
|
<div class="col-md-6">
|
||||||
<label class="form-label">{{.Version}}</label>
|
<label class="form-label">{{.Version}}</label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<br/>
|
<br/>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<label class="col-sm-2 control-label form-label">Register a New User</label>
|
<label class="col-sm-2 control-label form-label">{{T "Register a New User"}}</label>
|
||||||
<div class="col-md-6">
|
<div class="col-md-6">
|
||||||
<a href="/register" class="btn btn-primary"><i class="fa fa-plus"></i> Add User</a>
|
<a href="/register" class="btn btn-primary"><i class="fa fa-plus"></i> {{T "Add User"}}</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<br/>
|
<br/>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<label for="api_key" class="col-sm-2 control-label form-label">API Key:</label>
|
<label for="api_key" class="col-sm-2 control-label form-label">{{T "API Key"}}:</label>
|
||||||
<div class="col-md-6">
|
<div class="col-md-6">
|
||||||
<input type="text" id="api_key" onclick="this.select();" value="{{.User.ApiKey}}" class="form-control" readonly/>
|
<input type="text" id="api_key" onclick="this.select();" value="{{.User.ApiKey}}" class="form-control" readonly/>
|
||||||
</div>
|
</div>
|
||||||
<form id="apiResetForm">
|
<form id="apiResetForm">
|
||||||
<button class="btn btn-primary"><i class="fa fa-refresh" type="submit"></i> Reset</button>
|
<button class="btn btn-primary"><i class="fa fa-refresh" type="submit"></i> {{T "Reset"}}</button>
|
||||||
<input type="hidden" name="csrf_token" value="{{.Token}}"/>
|
<input type="hidden" name="csrf_token" value="{{.Token}}"/>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
<br />
|
<br />
|
||||||
<form id="settingsForm">
|
<form id="settingsForm">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<label for="username" class="col-sm-2 control-label form-label">Username:</label>
|
<label for="username" class="col-sm-2 control-label form-label">{{T "Username"}}:</label>
|
||||||
<div class="col-md-6">
|
<div class="col-md-6">
|
||||||
<input type="text" id="username" name="username" value="{{.User.Username}}" class="form-control" />
|
<input type="text" id="username" name="username" value="{{.User.Username}}" class="form-control" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<br />
|
<br />
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<label for="current_password" class="col-sm-2 control-label form-label">Old Password:</label>
|
<label for="current_password" class="col-sm-2 control-label form-label">{{T "Old Password"}}:</label>
|
||||||
<div class="col-md-6">
|
<div class="col-md-6">
|
||||||
<input type="password" id="current_password" name="current_password" autocomplete="off" class="form-control"/>
|
<input type="password" id="current_password" name="current_password" autocomplete="off" class="form-control"/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<br />
|
<br />
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<label for="new_password" class="col-sm-2 control-label form-label">New Password:</label>
|
<label for="new_password" class="col-sm-2 control-label form-label">{{T "New Password"}}:</label>
|
||||||
<div class="col-md-6">
|
<div class="col-md-6">
|
||||||
<input type="password" id="new_password" name="new_password" autocomplete="off" class="form-control" />
|
<input type="password" id="new_password" name="new_password" autocomplete="off" class="form-control" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<br />
|
<br />
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<label for="confirm_new_password" class="col-sm-2 control-label form-label">Confirm New Password:</label>
|
<label for="confirm_new_password" class="col-sm-2 control-label form-label">{{T "Confirm New Password"}}:</label>
|
||||||
<div class="col-md-6">
|
<div class="col-md-6">
|
||||||
<input type="password" id="confirm_new_password" name="confirm_new_password" autocomplete="off" class="form-control" />
|
<input type="password" id="confirm_new_password" name="confirm_new_password" autocomplete="off" class="form-control" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<input type="hidden" name="csrf_token" value="{{.Token}}"/>
|
<input type="hidden" name="csrf_token" value="{{.Token}}"/>
|
||||||
<br />
|
<br />
|
||||||
<button class="btn btn-primary" type="submit"><i class="fa fa-save"></i> Save</button>
|
<button class="btn btn-primary" type="submit"><i class="fa fa-save"></i> {{T "Save"}}</button>
|
||||||
</form>
|
</form>
|
||||||
<br/>
|
<br/>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -3,24 +3,24 @@
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-sm-3 col-md-2 sidebar">
|
<div class="col-sm-3 col-md-2 sidebar">
|
||||||
<ul class="nav nav-sidebar">
|
<ul class="nav nav-sidebar">
|
||||||
<li><a href="/">Dashboard</a>
|
<li><a href="/">{{T "Dashboard"}}</a>
|
||||||
</li>
|
</li>
|
||||||
<li><a href="/campaigns">Campaigns</a>
|
<li><a href="/campaigns">{{T "Campaigns"}}</a>
|
||||||
</li>
|
</li>
|
||||||
<li><a href="/users">Users & Groups</a>
|
<li><a href="/users">{{T "Users & Groups"}}</a>
|
||||||
</li>
|
</li>
|
||||||
<li class="active"><a href="/templates">Email Templates</a>
|
<li class="active"><a href="/templates">{{T "Email Templates"}}</a>
|
||||||
</li>
|
</li>
|
||||||
<li><a href="/landing_pages">Landing Pages</a>
|
<li><a href="/landing_pages">{{T "Landing Pages"}}</a>
|
||||||
</li>
|
</li>
|
||||||
<li><a href="/sending_profiles">Sending Profiles</a>
|
<li><a href="/sending_profiles">{{T "Sending Profiles"}}</a>
|
||||||
</li>
|
</li>
|
||||||
<li><a href="/settings">Settings</a>
|
<li><a href="/settings">{{T "Settings"}}</a>
|
||||||
</li>
|
</li>
|
||||||
<li><hr></li>
|
<li><hr></li>
|
||||||
<li><a href="https://gophish.gitbooks.io/user-guide/content/">User Guide</a>
|
<li><a href="https://gophish.gitbooks.io/user-guide/content/">{{T "User Guide"}}</a>
|
||||||
</li>
|
</li>
|
||||||
<li><a href="/api/">API Documentation</a>
|
<li><a href="/api/">{{T "API Documentation"}}</a>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
@ -29,12 +29,12 @@
|
||||||
<div class="col-sm-9 col-sm-offset-3 col-md-10 col-md-offset-2 main">
|
<div class="col-sm-9 col-sm-offset-3 col-md-10 col-md-offset-2 main">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<h1 class="page-header">
|
<h1 class="page-header">
|
||||||
Email Templates
|
{{T "Email Templates"}}
|
||||||
</h1>
|
</h1>
|
||||||
</div>
|
</div>
|
||||||
<div id="flashes" class="row"></div>
|
<div id="flashes" class="row"></div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<button type="button" class="btn btn-primary" onclick="edit(-1)" data-toggle="modal" data-target="#modal"><i class="fa fa-plus"></i> New Template</button>
|
<button type="button" class="btn btn-primary" onclick="edit(-1)" data-toggle="modal" data-target="#modal"><i class="fa fa-plus"></i> {{T "New Template"}}</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="loading">
|
<div id="loading">
|
||||||
|
@ -42,15 +42,15 @@
|
||||||
</div>
|
</div>
|
||||||
<div id="emptyMessage" class="row" style="display:none;">
|
<div id="emptyMessage" class="row" style="display:none;">
|
||||||
<div class="alert alert-info">
|
<div class="alert alert-info">
|
||||||
No templates yet. Let's create one!
|
{{T "No templates yet. Let's create one!"}}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<table id="templateTable" class="table" style="display:none;">
|
<table id="templateTable" class="table" style="display:none;">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th>Name</th>
|
<th>{{T "Name"}}</th>
|
||||||
<th>Modified Date</th>
|
<th>{{T "Modified Date"}}</th>
|
||||||
<th class="col-md-2 no-sort"></th>
|
<th class="col-md-2 no-sort"></th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
|
@ -66,30 +66,30 @@
|
||||||
<!-- New Template Modal -->
|
<!-- New Template Modal -->
|
||||||
<div class="modal-header">
|
<div class="modal-header">
|
||||||
<button type="button" class="close" data-dismiss="modal" aria-label="Close" onclick="dismiss()"><span aria-hidden="true">×</span></button>
|
<button type="button" class="close" data-dismiss="modal" aria-label="Close" onclick="dismiss()"><span aria-hidden="true">×</span></button>
|
||||||
<h4 class="modal-title" id="templateModalLabel">New Template</h4>
|
<h4 class="modal-title" id="templateModalLabel">{{T "New Template"}}</h4>
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-body">
|
<div class="modal-body">
|
||||||
<div class="row" id="modal.flashes"></div>
|
<div class="row" id="modal.flashes"></div>
|
||||||
<label class="control-label" for="name">Name:</label>
|
<label class="control-label" for="name">{{T "Name"}}:</label>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<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" data-toggle="modal" data-target="#importEmailModal"><i class="fa fa-envelope"></i> Import Email</button>
|
<button class="btn btn-danger" data-toggle="modal" data-target="#importEmailModal"><i class="fa fa-envelope"></i> {{T "Import Email"}}</button>
|
||||||
</div>
|
</div>
|
||||||
<label class="control-label" for="subject">Subject:</label>
|
<label class="control-label" for="subject">{{T "Subject"}}:</label>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<input type="text" class="form-control" placeholder="Email Subject" id="subject" />
|
<input type="text" class="form-control" placeholder="{{T "Email Subject"}}" id="subject" />
|
||||||
</div>
|
</div>
|
||||||
<!-- Nav tabs -->
|
<!-- Nav tabs -->
|
||||||
<ul class="nav nav-tabs" role="tablist">
|
<ul class="nav nav-tabs" role="tablist">
|
||||||
<li class="active" role="text"><a href="#text" aria-controls="text" role="tab" data-toggle="tab">Text</a></li>
|
<li class="active" role="text"><a href="#text" aria-controls="text" role="tab" data-toggle="tab">{{T "Text"}}</a></li>
|
||||||
<li role="html"><a href="#html" aria-controls="html" role="tab" data-toggle="tab">HTML</a></li>
|
<li role="html"><a href="#html" aria-controls="html" role="tab" data-toggle="tab">{{T "HTML"}}</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
<!-- Tab panes -->
|
<!-- Tab panes -->
|
||||||
<div class="tab-content">
|
<div class="tab-content">
|
||||||
<div role="tabpanel" class="tab-pane active" id="text">
|
<div role="tabpanel" class="tab-pane active" id="text">
|
||||||
<textarea rows="10" id="text_editor" class="gophish-editor form-control" placeholder="Plaintext"></textarea>
|
<textarea rows="10" id="text_editor" class="gophish-editor form-control" placeholder="{{T "Plaintext"}}"></textarea>
|
||||||
</div>
|
</div>
|
||||||
<div role="tabpanel" class="tab-pane" id="html">
|
<div role="tabpanel" class="tab-pane" id="html">
|
||||||
<textarea id="html_editor"></textarea>
|
<textarea id="html_editor"></textarea>
|
||||||
|
@ -97,9 +97,9 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="checkbox checkbox-primary">
|
<div class="checkbox checkbox-primary">
|
||||||
<input id="use_tracker_checkbox" type="checkbox" checked>
|
<input id="use_tracker_checkbox" type="checkbox" checked>
|
||||||
<label for="use_tracker_checkbox">Add Tracking Image</label>
|
<label for="use_tracker_checkbox">{{T "Add Tracking Image"}}</label>
|
||||||
</div>
|
</div>
|
||||||
<span class="btn btn-danger btn-file"><i class="fa fa-plus"></i> Add Files
|
<span class="btn btn-danger btn-file"><i class="fa fa-plus"></i> {{T "Add Files"}}
|
||||||
<input id="attachmentUpload" type="file" onchange="attach(this.files)" multiple>
|
<input id="attachmentUpload" type="file" onchange="attach(this.files)" multiple>
|
||||||
</span>
|
</span>
|
||||||
<br />
|
<br />
|
||||||
|
@ -108,10 +108,10 @@
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th class="col-md-1 no-sort"></th>
|
<th class="col-md-1 no-sort"></th>
|
||||||
<th class="col-md-10">Name</th>
|
<th class="col-md-10">{{T "Name"}}</th>
|
||||||
<th class="col-md-1 no-sort"></th>
|
<th class="col-md-1 no-sort"></th>
|
||||||
<th class="datatable_hidden no-sort">Content</th>
|
<th class="datatable_hidden no-sort">{{T "Content"}}</th>
|
||||||
<th class="datatable_hidden no-sort">Type</th>
|
<th class="datatable_hidden no-sort">{{T "Type"}}</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
|
@ -119,8 +119,8 @@
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-footer">
|
<div class="modal-footer">
|
||||||
<button type="button" data-dismiss="modal" class="btn btn-default" onclick="dismiss()">Cancel</button>
|
<button type="button" data-dismiss="modal" class="btn btn-default" onclick="dismiss()">{{T "Cancel"}}</button>
|
||||||
<button type="button" class="btn btn-primary" id="modalSubmit">Save Template</button>
|
<button type="button" class="btn btn-primary" id="modalSubmit">{{T "Save Template"}}</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -132,22 +132,22 @@
|
||||||
<!-- New Email Modal -->
|
<!-- New Email Modal -->
|
||||||
<div class="modal-header">
|
<div class="modal-header">
|
||||||
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
|
<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>
|
<h4 class="modal-title" id="importEmailModalLabel">{{T "Import Email"}}</h4>
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-body">
|
<div class="modal-body">
|
||||||
<div class="row" id="modal.flashes"></div>
|
<div class="row" id="modal.flashes"></div>
|
||||||
<label class="control-label" for="email">Email Content:</label>
|
<label class="control-label" for="email">{{T "Email Content"}}:</label>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<textarea rows="10" id="email_content" class="gophish-editor form-control" placeholder="Raw Email Source"></textarea>
|
<textarea rows="10" id="email_content" class="gophish-editor form-control" placeholder="{{T "Raw Email Source"}}"></textarea>
|
||||||
</div>
|
</div>
|
||||||
<div class="checkbox checkbox-primary">
|
<div class="checkbox checkbox-primary">
|
||||||
<input id="convert_links_checkbox" type="checkbox" checked>
|
<input id="convert_links_checkbox" type="checkbox" checked>
|
||||||
<label for="convert_links_checkbox">Change Links to Point to Landing Page</label>
|
<label for="convert_links_checkbox">{{T "Change Links to Point to Landing Page"}}</label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-footer">
|
<div class="modal-footer">
|
||||||
<button type="button" data-dismiss="modal" class="btn btn-default">Cancel</button>
|
<button type="button" data-dismiss="modal" class="btn btn-default">{{T "Cancel"}}</button>
|
||||||
<button type="button" class="btn btn-primary" id="modalSubmit" onclick="importEmail()">Import</button>
|
<button type="button" class="btn btn-primary" id="modalSubmit" onclick="importEmail()">{{T "Import"}}</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -3,24 +3,24 @@
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-sm-3 col-md-2 sidebar">
|
<div class="col-sm-3 col-md-2 sidebar">
|
||||||
<ul class="nav nav-sidebar">
|
<ul class="nav nav-sidebar">
|
||||||
<li><a href="/">Dashboard</a>
|
<li><a href="/">{{T "Dashboard"}}</a>
|
||||||
</li>
|
</li>
|
||||||
<li><a href="/campaigns">Campaigns</a>
|
<li><a href="/campaigns">{{T "Campaigns"}}</a>
|
||||||
</li>
|
</li>
|
||||||
<li class="active"><a href="#/users">Users & Groups</a>
|
<li class="active"><a href="#/users">{{T "Users & Groups"}}</a>
|
||||||
</li>
|
</li>
|
||||||
<li><a href="/templates">Email Templates</a>
|
<li><a href="/templates">{{T "Email Templates"}}</a>
|
||||||
</li>
|
</li>
|
||||||
<li><a href="/landing_pages">Landing Pages</a>
|
<li><a href="/landing_pages">{{T "Landing Pages"}}</a>
|
||||||
</li>
|
</li>
|
||||||
<li><a href="/sending_profiles">Sending Profiles</a>
|
<li><a href="/sending_profiles">{{T "Sending Profiles"}}</a>
|
||||||
</li>
|
</li>
|
||||||
<li><a href="/settings">Settings</a>
|
<li><a href="/settings">{{T "Settings"}}</a>
|
||||||
</li>
|
</li>
|
||||||
<li><hr></li>
|
<li><hr></li>
|
||||||
<li><a href="https://gophish.gitbooks.io/user-guide/content/">User Guide</a>
|
<li><a href="https://gophish.gitbooks.io/user-guide/content/">{{T "User Guide"}}</a>
|
||||||
</li>
|
</li>
|
||||||
<li><a href="/api/">API Documentation</a>
|
<li><a href="/api/">{{T "API Documentation"}}</a>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
@ -29,12 +29,12 @@
|
||||||
<div class="col-sm-9 col-sm-offset-3 col-md-10 col-md-offset-2 main">
|
<div class="col-sm-9 col-sm-offset-3 col-md-10 col-md-offset-2 main">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<h1 class="page-header">
|
<h1 class="page-header">
|
||||||
Users & Groups
|
{{T "Users & Groups"}}
|
||||||
</h1>
|
</h1>
|
||||||
</div>
|
</div>
|
||||||
<div id="flashes" class="row"></div>
|
<div id="flashes" class="row"></div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<button type="button" class="btn btn-primary" onclick="edit(-1)" data-toggle="modal" data-target="#modal"><i class="fa fa-plus"></i> New Group</button>
|
<button type="button" class="btn btn-primary" onclick="edit(-1)" data-toggle="modal" data-target="#modal"><i class="fa fa-plus"></i> {{T "New Group"}}</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="loading">
|
<div id="loading">
|
||||||
|
@ -42,16 +42,16 @@
|
||||||
</div>
|
</div>
|
||||||
<div id="emptyMessage" class="row" style="display:none;">
|
<div id="emptyMessage" class="row" style="display:none;">
|
||||||
<div class="alert alert-info">
|
<div class="alert alert-info">
|
||||||
No groups created yet. Let's create one!
|
{{T "No groups created yet. Let's create one!"}}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<table id="groupTable" class="table" style="display:none;">
|
<table id="groupTable" class="table" style="display:none;">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th>Name</th>
|
<th>{{T "Name"}}</th>
|
||||||
<th># of Members</th>
|
<th>{{T "# of Members"}}</th>
|
||||||
<th>Modified Date</th>
|
<th>{{T "Modified Date"}}</th>
|
||||||
<th class="col-md-2 no-sort"></th>
|
<th class="col-md-2 no-sort"></th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
|
@ -66,35 +66,35 @@
|
||||||
<div class="modal-content">
|
<div class="modal-content">
|
||||||
<div class="modal-header">
|
<div class="modal-header">
|
||||||
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
|
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
|
||||||
<h4 class="modal-title" id="groupModalLabel">New Group</h4>
|
<h4 class="modal-title" id="groupModalLabel">{{T "New Group"}}</h4>
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-body">
|
<div class="modal-body">
|
||||||
<div class="row" id="modal.flashes"></div>
|
<div class="row" id="modal.flashes"></div>
|
||||||
<label class="control-label" for="name">Name:</label>
|
<label class="control-label" for="name">{{T "Name"}}:</label>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<input type="text" class="form-control" ng-model="group.name" placeholder="Group name" id="name" autofocus/>
|
<input type="text" class="form-control" ng-model="group.name" placeholder="{{T "Group name"}}" id="name" autofocus/>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<span class="btn btn-danger btn-file" data-toggle="tooltip" data-placement="right" title="Supports CSV files" id="fileUpload"><i class="fa fa-plus"></i> Bulk Import Users
|
<span class="btn btn-danger btn-file" data-toggle="tooltip" data-placement="right" title="{{T "Supports CSV files"}}" id="fileUpload"><i class="fa fa-plus"></i> {{T "Bulk Import Users"}}
|
||||||
<input type="file" id="csvupload" data-url="/api/import/group" multiple>
|
<input type="file" id="csvupload" data-url="/api/import/group" multiple>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<form id="targetForm">
|
<form id="targetForm">
|
||||||
<div class="col-sm-2">
|
<div class="col-sm-2">
|
||||||
<input type="text" class="form-control" placeholder="First Name" id="firstName">
|
<input type="text" class="form-control" placeholder="{{T "First Name"}}" id="firstName">
|
||||||
</div>
|
</div>
|
||||||
<div class="col-sm-2">
|
<div class="col-sm-2">
|
||||||
<input type="text" class="form-control" placeholder="Last Name" id="lastName">
|
<input type="text" class="form-control" placeholder="{{T "Last Name"}}" id="lastName">
|
||||||
</div>
|
</div>
|
||||||
<div class="col-sm-3">
|
<div class="col-sm-3">
|
||||||
<input type="email" class="form-control" placeholder="Email" id="email" required>
|
<input type="email" class="form-control" placeholder="{{T "Email"}}" id="email" required>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-sm-3">
|
<div class="col-sm-3">
|
||||||
<input type="text" class="form-control" placeholder="Position" id="position">
|
<input type="text" class="form-control" placeholder="{{T "Position"}}" id="position">
|
||||||
</div>
|
</div>
|
||||||
<div class="col-sm-1">
|
<div class="col-sm-1">
|
||||||
<button type="submit" class="btn btn-danger btn-lg"><i class="fa fa-plus"></i> Add</button>
|
<button type="submit" class="btn btn-danger btn-lg"><i class="fa fa-plus"></i> {{T "Add"}}</button>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
@ -102,18 +102,18 @@
|
||||||
<table id="targetsTable" class="table table-hover table-striped table-condensed">
|
<table id="targetsTable" class="table table-hover table-striped table-condensed">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th>First Name</th>
|
<th>{{T "First Name"}}</th>
|
||||||
<th>Last Name</th>
|
<th>{{T "Last Name"}}</th>
|
||||||
<th>Email</th>
|
<th>{{T "Email"}}</th>
|
||||||
<th>Position</th>
|
<th>{{T "Position"}}</th>
|
||||||
<th class="no-sort"></th>
|
<th class="no-sort"></th>
|
||||||
<tbody>
|
<tbody>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-footer">
|
<div class="modal-footer">
|
||||||
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
|
<button type="button" class="btn btn-default" data-dismiss="modal">{{T "Close"}}</button>
|
||||||
<button type="button" class="btn btn-primary" id="modalSubmit">Save changes</button>
|
<button type="button" class="btn btn-primary" id="modalSubmit">{{T "Save changes"}}</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
10
util/util.go
10
util/util.go
|
@ -21,11 +21,21 @@ import (
|
||||||
|
|
||||||
"github.com/gophish/gophish/models"
|
"github.com/gophish/gophish/models"
|
||||||
"github.com/jordan-wright/email"
|
"github.com/jordan-wright/email"
|
||||||
|
"github.com/nicksnyder/go-i18n/i18n"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Logger is used to send logging messages to stdout.
|
// Logger is used to send logging messages to stdout.
|
||||||
var Logger = log.New(os.Stdout, " ", log.Ldate|log.Ltime|log.Lshortfile)
|
var Logger = log.New(os.Stdout, " ", log.Ldate|log.Ltime|log.Lshortfile)
|
||||||
|
|
||||||
|
func T(text string) string{
|
||||||
|
T, _ := i18n.Tfunc("en-US", "en-US")
|
||||||
|
result := T(text)
|
||||||
|
if result == text {
|
||||||
|
fmt.Println("NON-TRANSLATION %s", text)
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
// ParseMail takes in an HTTP Request and returns an Email object
|
// ParseMail takes in an HTTP Request and returns an Email object
|
||||||
// TODO: This function will likely be changed to take in a []byte
|
// TODO: This function will likely be changed to take in a []byte
|
||||||
func ParseMail(r *http.Request) (email.Email, error) {
|
func ParseMail(r *http.Request) (email.Email, error) {
|
||||||
|
|
Loading…
Reference in New Issue