diff --git a/.circleci/config.yml b/.circleci/config.yml index 1e3586300..df323398f 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -38,7 +38,7 @@ commands: - run: name: Build and push application container image command: | - serverImageTag="eu.gcr.io/<< parameters.imageProjectId >>/${APP_NAME}-image:<< parameters.tagNumber >>" + serverImageTag="europe-west1-docker.pkg.dev/<< parameters.imageProjectId >>/${APP_NAME}-repository/${APP_NAME}-image:<< parameters.tagNumber >>" docker build -t ${serverImageTag} --file Dockerfile . docker push ${serverImageTag} @@ -49,8 +49,8 @@ jobs: executor: gcp steps: - build_and_push_image: - imageProjectId: "eqt-i9n-infra-test" - tagNumber: "4" + imageProjectId: "eqt-cicd-prod" + tagNumber: "5" workflows: version: 2.1 diff --git a/Dockerfile b/Dockerfile index c8869be95..63af4e127 100644 --- a/Dockerfile +++ b/Dockerfile @@ -23,7 +23,7 @@ FROM debian:stable-slim RUN useradd -m -d /opt/gophish -s /bin/bash app RUN apt-get update && \ - apt-get install --no-install-recommends -y jq libcap2-bin && \ + apt-get install --no-install-recommends -y jq libcap2-bin ca-certificates && \ apt-get clean && \ rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* diff --git a/docker/run.sh b/docker/run.sh index bdfc22fac..76dee78b0 100755 --- a/docker/run.sh +++ b/docker/run.sh @@ -66,6 +66,14 @@ if [ -n "${CONTACT_ADDRESS+set}" ] ; then cat config.json.tmp > config.json fi +# db_name has to be changed to mysql for mysql connection to work +if [ -n "${DB_NAME+set}" ] ; then + jq -r \ + --arg DB_NAME "${DB_NAME}" \ + '.db_name = $DB_NAME' config.json > config.json.tmp && \ + cat config.json.tmp > config.json +fi + if [ -n "${DB_FILE_PATH+set}" ] ; then jq -r \ --arg DB_FILE_PATH "${DB_FILE_PATH}" \ diff --git a/models/maillog_test.go b/models/maillog_test.go index 88619f937..54895413d 100644 --- a/models/maillog_test.go +++ b/models/maillog_test.go @@ -284,7 +284,7 @@ func (s *ModelsSuite) TestMailLogGenerateOverrideTransparencyHeaders(ch *check.C smtp := SMTP{ Name: "Test SMTP", Host: "1.1.1.1:25", - FromAddress: "Foo Bar ", + FromAddress: "foo@example.com", UserId: 1, Headers: []Header{ Header{Key: "X-Gophish-Contact", Value: ""}, diff --git a/models/smtp.go b/models/smtp.go index cd4d4e232..89796457e 100644 --- a/models/smtp.go +++ b/models/smtp.go @@ -5,6 +5,7 @@ import ( "errors" "net/mail" "os" + "regexp" "strconv" "strings" "time" @@ -57,6 +58,10 @@ type Header struct { // specified in the SMTP configuration var ErrFromAddressNotSpecified = errors.New("No From Address specified") +// ErrInvalidFromAddress is thrown when the SMTP From field in the sending +// profiles containes a value that is not an email address +var ErrInvalidFromAddress = errors.New("Invalid SMTP From address because it is not an email address") + // ErrHostNotSpecified is thrown when there is no Host specified // in the SMTP configuration var ErrHostNotSpecified = errors.New("No SMTP Host specified") @@ -76,6 +81,8 @@ func (s *SMTP) Validate() error { return ErrFromAddressNotSpecified case s.Host == "": return ErrHostNotSpecified + case !validateFromAddress(s.FromAddress): + return ErrInvalidFromAddress } _, err := mail.ParseAddress(s.FromAddress) if err != nil { @@ -95,6 +102,12 @@ func (s *SMTP) Validate() error { return err } +// validateFromAddress validates +func validateFromAddress(email string) bool { + r, _ := regexp.Compile("^([a-zA-Z0-9_\\-\\.]+)@([a-zA-Z0-9_\\-\\.]+)\\.([a-zA-Z]{2,18})$") + return r.MatchString(email) +} + // GetDialer returns a dialer for the given SMTP profile func (s *SMTP) GetDialer() (mailer.Dialer, error) { // Setup the message and dial diff --git a/models/smtp_test.go b/models/smtp_test.go index b559c2829..f4f1ab60a 100644 --- a/models/smtp_test.go +++ b/models/smtp_test.go @@ -12,7 +12,7 @@ func (s *ModelsSuite) TestPostSMTP(c *check.C) { smtp := SMTP{ Name: "Test SMTP", Host: "1.1.1.1:25", - FromAddress: "Foo Bar ", + FromAddress: "foo@example.com", UserId: 1, } err := PostSMTP(&smtp) @@ -25,7 +25,7 @@ func (s *ModelsSuite) TestPostSMTP(c *check.C) { func (s *ModelsSuite) TestPostSMTPNoHost(c *check.C) { smtp := SMTP{ Name: "Test SMTP", - FromAddress: "Foo Bar ", + FromAddress: "foo@example.com", UserId: 1, } err := PostSMTP(&smtp) @@ -42,12 +42,34 @@ func (s *ModelsSuite) TestPostSMTPNoFrom(c *check.C) { c.Assert(err, check.Equals, ErrFromAddressNotSpecified) } -func (s *ModelsSuite) TestPostSMTPValidHeader(c *check.C) { +func (s *ModelsSuite) TestPostInvalidFrom(c *check.C) { smtp := SMTP{ Name: "Test SMTP", Host: "1.1.1.1:25", FromAddress: "Foo Bar ", UserId: 1, + } + err := PostSMTP(&smtp) + c.Assert(err, check.Equals, ErrInvalidFromAddress) +} + +func (s *ModelsSuite) TestPostInvalidFromEmail(c *check.C) { + smtp := SMTP{ + Name: "Test SMTP", + Host: "1.1.1.1:25", + FromAddress: "example.com", + UserId: 1, + } + err := PostSMTP(&smtp) + c.Assert(err, check.Equals, ErrInvalidFromAddress) +} + +func (s *ModelsSuite) TestPostSMTPValidHeader(c *check.C) { + smtp := SMTP{ + Name: "Test SMTP", + Host: "1.1.1.1:25", + FromAddress: "foo@example.com", + UserId: 1, Headers: []Header{ Header{Key: "Reply-To", Value: "test@example.com"}, Header{Key: "X-Mailer", Value: "gophish"}, diff --git a/static/js/dist/app/campaign_results.min.js b/static/js/dist/app/campaign_results.min.js index 8923dfc9b..e98bddc9a 100644 --- a/static/js/dist/app/campaign_results.min.js +++ b/static/js/dist/app/campaign_results.min.js @@ -1 +1 @@ -var map=null,doPoll=!0,statuses={"Email Sent":{color:"#1abc9c",label:"label-success",icon:"fa-envelope",point:"ct-point-sent"},"Emails Sent":{color:"#1abc9c",label:"label-success",icon:"fa-envelope",point:"ct-point-sent"},"In progress":{label:"label-primary"},Queued:{label:"label-info"},Completed:{label:"label-success"},"Email Opened":{color:"#f9bf3b",label:"label-warning",icon:"fa-envelope-open",point:"ct-point-opened"},"Clicked Link":{color:"#F39C12",label:"label-clicked",icon:"fa-mouse-pointer",point:"ct-point-clicked"},Success:{color:"#f05b4f",label:"label-danger",icon:"fa-exclamation",point:"ct-point-clicked"},"Email Reported":{color:"#45d6ef",label:"label-info",icon:"fa-bullhorn",point:"ct-point-reported"},Error:{color:"#6c7a89",label:"label-default",icon:"fa-times",point:"ct-point-error"},"Error Sending Email":{color:"#6c7a89",label:"label-default",icon:"fa-times",point:"ct-point-error"},"Submitted Data":{color:"#f05b4f",label:"label-danger",icon:"fa-exclamation",point:"ct-point-clicked"},Unknown:{color:"#6c7a89",label:"label-default",icon:"fa-question",point:"ct-point-error"},Sending:{color:"#428bca",label:"label-primary",icon:"fa-spinner",point:"ct-point-sending"},Retrying:{color:"#6c7a89",label:"label-default",icon:"fa-clock-o",point:"ct-point-error"},Scheduled:{color:"#428bca",label:"label-primary",icon:"fa-clock-o",point:"ct-point-sending"},"Campaign Created":{label:"label-success",icon:"fa-rocket"}},statusMapping={"Email Sent":"sent","Email Opened":"opened","Clicked Link":"clicked","Submitted Data":"submitted_data","Email Reported":"reported"},progressListing=["Email Sent","Email Opened","Clicked Link","Submitted Data"],campaign={},bubbles=[];function dismiss(){$("#modal\\.flashes").empty(),$("#modal").modal("hide"),$("#resultsTable").dataTable().DataTable().clear().draw()}function deleteCampaign(){Swal.fire({title:"Are you sure?",text:"This will delete the campaign. This can't be undone!",type:"warning",animation:!1,showCancelButton:!0,confirmButtonText:"Delete Campaign",confirmButtonColor:"#428bca",reverseButtons:!0,allowOutsideClick:!1,showLoaderOnConfirm:!0,preConfirm:function(){return new Promise(function(t,a){api.campaignId.delete(campaign.id).success(function(e){t()}).error(function(e){a(e.responseJSON.message)})})}}).then(function(e){e.value&&Swal.fire("Campaign Deleted!","This campaign has been deleted!","success"),$('button:contains("OK")').on("click",function(){location.href="/campaigns"})})}function completeCampaign(){Swal.fire({title:"Are you sure?",text:"Gophish will stop processing events for this campaign",type:"warning",animation:!1,showCancelButton:!0,confirmButtonText:"Complete Campaign",confirmButtonColor:"#428bca",reverseButtons:!0,allowOutsideClick:!1,showLoaderOnConfirm:!0,preConfirm:function(){return new Promise(function(t,a){api.campaignId.complete(campaign.id).success(function(e){t()}).error(function(e){a(e.responseJSON.message)})})}}).then(function(e){e.value&&(Swal.fire("Campaign Completed!","This campaign has been completed!","success"),$("#complete_button")[0].disabled=!0,$("#complete_button").text("Completed!"),doPoll=!1)})}function exportAsCSV(e){exportHTML=$("#exportButton").html();var t=null,a=campaign.name+" - "+capitalize(e)+".csv";switch(e){case"results":t=campaign.results;break;case"events":t=campaign.timeline}if(t){$("#exportButton").html('');var s=Papa.unparse(t,{escapeFormulae:!0}),i=new Blob([s],{type:"text/csv;charset=utf-8;"});if(navigator.msSaveBlob)navigator.msSaveBlob(i,a);else{var l=window.URL.createObjectURL(i),n=document.createElement("a");n.href=l,n.setAttribute("download",a),document.body.appendChild(n),n.click(),document.body.removeChild(n)}$("#exportButton").html(exportHTML)}}function replay(e){return request=campaign.timeline[e],details=JSON.parse(request.details),url=null,form=$("
").attr({method:"POST",target:"_blank"}),$.each(Object.keys(details.payload),function(e,t){return"rid"==t||("__original_url"==t?(url=details.payload[t],!0):void $("").attr({name:t}).val(details.payload[t]).appendTo(form))}),void Swal.fire({title:"Where do you want the credentials submitted to?",input:"text",showCancelButton:!0,inputPlaceholder:"http://example.com/login",inputValue:url||"",inputValidator:function(a){return new Promise(function(e,t){a?e():t("Invalid URL.")})}}).then(function(e){e.value&&(url=e.value,t())});function t(){form.attr({action:url}),form.appendTo("body").submit().remove()}}var renderDevice=function(e){var t=UAParser(details.browser["user-agent"]),a='
',s="laptop";t.device.type&&("tablet"!=t.device.type&&"mobile"!=t.device.type||(s=t.device.type));var i="";t.device.vendor&&"microsoft"==(i=t.device.vendor.toLowerCase())&&(i="windows");var l="Unknown";t.os.name&&("Mac OS"==(l=t.os.name)?i="apple":"Windows"==l&&(i="windows"),t.device.vendor&&t.device.model&&(l=t.device.vendor+" "+t.device.model)),t.os.version&&(l=l+" (OS Version: "+t.os.version+")"),deviceString='
'+escapeHtml(l)+"
",a+=deviceString;var n="Unknown",r="info-circle",o="";return t.browser&&t.browser.name&&((n=(n=t.browser.name).replace("Mobile ",""))&&"ie"==(r=n.toLowerCase())&&(r="internet-explorer"),o="(Version: "+t.browser.version+")"),a+='
'+n+" "+o+"
",a+="
"};function renderTimeline(e){return record={id:e[0],first_name:e[2],last_name:e[3],email:e[4],position:e[5],status:e[6],reported:e[7],send_date:e[8]},results='
Timeline for '+escapeHtml(record.first_name)+" "+escapeHtml(record.last_name)+'
Email: '+escapeHtml(record.email)+"
Result ID: "+escapeHtml(record.id)+'
',$.each(campaign.timeline,function(e,t){t.email&&t.email!=record.email||(results+='
',results+='
'+escapeHtml(t.message)+' '+moment.utc(t.time).local().format("MMMM Do YYYY h:mm:ss a")+"",t.details&&(details=JSON.parse(t.details),"Clicked Link"!=t.message&&"Submitted Data"!=t.message||(deviceView=renderDevice(details),deviceView&&(results+=deviceView)),"Submitted Data"==t.message&&(results+='
',results+='
View Details
'),details.payload&&(results+='
',results+=' ',results+=" ",$.each(Object.keys(details.payload),function(e,t){if("rid"==t)return!0;results+=" ",results+=" ",results+=" ",results+=" "}),results+="
ParameterValue(s)
"+escapeHtml(t)+""+escapeHtml(details.payload[t])+"
",results+="
"),details.error&&(results+='
View Details
',results+='
',results+='Error '+details.error,results+="
")),results+="
")}),"Scheduled"!=record.status&&"Retrying"!=record.status||(results+='
',results+='
Scheduled to send at '+record.send_date+""),results+="
",results}var setRefresh,renderTimelineChart=function(e){return Highcharts.chart("timeline_chart",{chart:{zoomType:"x",type:"line",height:"200px"},title:{text:"Campaign Timeline"},xAxis:{type:"datetime",dateTimeLabelFormats:{second:"%l:%M:%S",minute:"%l:%M",hour:"%l:%M",day:"%b %d, %Y",week:"%b %d, %Y",month:"%b %Y"}},yAxis:{min:0,max:2,visible:!1,tickInterval:1,labels:{enabled:!1},title:{text:""}},tooltip:{formatter:function(){return Highcharts.dateFormat("%A, %b %d %l:%M:%S %P",new Date(this.x))+"
Event: "+this.point.message+"
Email: "+this.point.email+""}},legend:{enabled:!1},plotOptions:{series:{marker:{enabled:!0,symbol:"circle",radius:3},cursor:"pointer"},line:{states:{hover:{lineWidth:1}}}},credits:{enabled:!1},series:[{data:e.data,dashStyle:"shortdash",color:"#cccccc",lineWidth:1,turboThreshold:0}]})},renderPieChart=function(l){return Highcharts.chart(l.elemId,{chart:{type:"pie",events:{load:function(){var e=this,t=e.renderer,a=e.series[0],s=e.plotLeft+a.center[0],i=e.plotTop+a.center[1];this.innerText=t.text(l.data[0].count,s,i).attr({"text-anchor":"middle","font-size":"24px","font-weight":"bold",fill:l.colors[0],"font-family":"Helvetica,Arial,sans-serif"}).add()},render:function(){this.innerText.attr({text:l.data[0].count})}}},title:{text:l.title},plotOptions:{pie:{innerSize:"80%",dataLabels:{enabled:!1}}},credits:{enabled:!1},tooltip:{formatter:function(){return null!=this.key&&''+this.point.name+": "+this.y+"%
"}},series:[{data:l.data,colors:l.colors}]})},updateMap=function(e){map&&(bubbles=[],$.each(campaign.results,function(e,a){if(0==a.latitude&&0==a.longitude)return!0;newIP=!0,$.each(bubbles,function(e,t){if(t.ip==a.ip)return bubbles[e].radius+=1,newIP=!1}),newIP&&bubbles.push({latitude:a.latitude,longitude:a.longitude,name:a.ip,fillKey:"point",radius:2})}),map.bubbles(bubbles))};function createStatusLabel(e,t){var a=statuses[e].label||"label-default",s=''+e+"";"Scheduled"!=e&&"Retrying"!=e||(s=''+e+"");return s}function poll(){api.campaignId.results(campaign.id).success(function(e){campaign=e;var s=[];$.each(campaign.timeline,function(e,t){var a=moment.utc(t.time).local();s.push({email:t.email,message:t.message,x:a.valueOf(),y:1,marker:{fillColor:statuses[t.message].color}})}),$("#timeline_chart").highcharts().series[0].update({data:s});var i={};Object.keys(statusMapping).forEach(function(e){i[e]=0}),$.each(campaign.results,function(e,t){i[t.status]++,t.reported&&i["Email Reported"]++;var a=progressListing.indexOf(t.status);for(e=0;e":"":e},targets:[7]}]}),resultsTable.clear();var s={},i=[];Object.keys(statusMapping).forEach(function(e){s[e]=0}),$.each(campaign.results,function(e,t){resultsTable.row.add([t.id,'',escapeHtml(t.first_name)||"",escapeHtml(t.last_name)||"",escapeHtml(t.email)||"",escapeHtml(t.position)||"",t.status,t.reported,moment(t.send_date).format("MMMM Do YYYY, h:mm:ss a")]),s[t.status]++,t.reported&&s["Email Reported"]++;var a=progressListing.indexOf(t.status);for(e=0;e');var csvString=Papa.unparse(csvScope,{escapeFormulae:true});var csvData=new Blob([csvString],{type:"text/csv;charset=utf-8;"});if(navigator.msSaveBlob){navigator.msSaveBlob(csvData,filename)}else{var csvURL=window.URL.createObjectURL(csvData);var dlLink=document.createElement("a");dlLink.href=csvURL;dlLink.setAttribute("download",filename);document.body.appendChild(dlLink);dlLink.click();document.body.removeChild(dlLink)}$("#exportButton").html(exportHTML)}function replay(event_idx){request=campaign.timeline[event_idx];details=JSON.parse(request.details);url=null;form=$("").attr({method:"POST",target:"_blank"});$.each(Object.keys(details.payload),function(i,param){if(param=="rid"){return true}if(param=="__original_url"){url=details.payload[param];return true}$("").attr({name:param}).val(details.payload[param]).appendTo(form)});Swal.fire({title:"Where do you want the credentials submitted to?",input:"text",showCancelButton:true,inputPlaceholder:"http://example.com/login",inputValue:url||"",inputValidator:function(value){return new Promise(function(resolve,reject){if(value){resolve()}else{reject("Invalid URL.")}})}}).then(function(result){if(result.value){url=result.value;submitForm()}});return;submitForm();function submitForm(){form.attr({action:url});form.appendTo("body").submit().remove()}}var renderDevice=function(event_details){var ua=UAParser(details.browser["user-agent"]);var detailsString='
';var deviceIcon="laptop";if(ua.device.type){if(ua.device.type=="tablet"||ua.device.type=="mobile"){deviceIcon=ua.device.type}}var deviceVendor="";if(ua.device.vendor){deviceVendor=ua.device.vendor.toLowerCase();if(deviceVendor=="microsoft")deviceVendor="windows"}var deviceName="Unknown";if(ua.os.name){deviceName=ua.os.name;if(deviceName=="Mac OS"){deviceVendor="apple"}else if(deviceName=="Windows"){deviceVendor="windows"}if(ua.device.vendor&&ua.device.model){deviceName=ua.device.vendor+" "+ua.device.model}}if(ua.os.version){deviceName=deviceName+" (OS Version: "+ua.os.version+")"}deviceString='
'+''+''+" "+escapeHtml(deviceName)+"
";detailsString+=deviceString;var deviceBrowser="Unknown";var browserIcon="info-circle";var browserVersion="";if(ua.browser&&ua.browser.name){deviceBrowser=ua.browser.name;deviceBrowser=deviceBrowser.replace("Mobile ","");if(deviceBrowser){browserIcon=deviceBrowser.toLowerCase();if(browserIcon=="ie")browserIcon="internet-explorer"}browserVersion="(Version: "+ua.browser.version+")"}var browserString='
'+' '+deviceBrowser+" "+browserVersion+"
";detailsString+=browserString;detailsString+="
";return detailsString};function renderTimeline(data){record={id:data[0],first_name:data[2],last_name:data[3],email:data[4],position:data[5],status:data[6],reported:data[7],send_date:data[8]};results='
'+"
Timeline for "+escapeHtml(record.first_name)+" "+escapeHtml(record.last_name)+'
Email: '+escapeHtml(record.email)+"
Result ID: "+escapeHtml(record.id)+"
"+'
';$.each(campaign.timeline,function(i,event){if(!event.email||event.email==record.email){results+='
'+'
';results+='
'+'
'+'
'+escapeHtml(event.message)+' '+moment.utc(event.time).local().format("MMMM Do YYYY h:mm:ss a")+"";if(event.details){details=JSON.parse(event.details);if(event.message=="Clicked Link"||event.message=="Submitted Data"){deviceView=renderDevice(details);if(deviceView){results+=deviceView}}if(event.message=="Submitted Data"){results+='
';results+='
View Details
'}if(details.payload){results+='
';results+=' ';results+=" ";$.each(Object.keys(details.payload),function(i,param){if(param=="rid"){return true}results+=" ";results+=" ";results+=" ";results+=" "});results+="
ParameterValue(s)
"+escapeHtml(param)+""+escapeHtml(details.payload[param])+"
";results+="
"}if(details.error){results+='
View Details
';results+='
';results+='Error '+details.error;results+="
"}}results+="
"}});if(record.status=="Scheduled"||record.status=="Retrying"){results+='
'+'
';results+='
'+'
'+'
'+"Scheduled to send at "+record.send_date+""}results+="
";return results}var renderTimelineChart=function(chartopts){return Highcharts.chart("timeline_chart",{chart:{zoomType:"x",type:"line",height:"200px"},title:{text:"Campaign Timeline"},xAxis:{type:"datetime",dateTimeLabelFormats:{second:"%l:%M:%S",minute:"%l:%M",hour:"%l:%M",day:"%b %d, %Y",week:"%b %d, %Y",month:"%b %Y"}},yAxis:{min:0,max:2,visible:false,tickInterval:1,labels:{enabled:false},title:{text:""}},tooltip:{formatter:function(){return Highcharts.dateFormat("%A, %b %d %l:%M:%S %P",new Date(this.x))+"
Event: "+this.point.message+"
Email: "+this.point.email+""}},legend:{enabled:false},plotOptions:{series:{marker:{enabled:true,symbol:"circle",radius:3},cursor:"pointer"},line:{states:{hover:{lineWidth:1}}}},credits:{enabled:false},series:[{data:chartopts["data"],dashStyle:"shortdash",color:"#cccccc",lineWidth:1,turboThreshold:0}]})};var renderPieChart=function(chartopts){return Highcharts.chart(chartopts["elemId"],{chart:{type:"pie",events:{load:function(){var chart=this,rend=chart.renderer,pie=chart.series[0],left=chart.plotLeft+pie.center[0],top=chart.plotTop+pie.center[1];this.innerText=rend.text(chartopts["data"][0].count,left,top).attr({"text-anchor":"middle","font-size":"24px","font-weight":"bold",fill:chartopts["colors"][0],"font-family":"Helvetica,Arial,sans-serif"}).add()},render:function(){this.innerText.attr({text:chartopts["data"][0].count})}}},title:{text:chartopts["title"]},plotOptions:{pie:{innerSize:"80%",dataLabels:{enabled:false}}},credits:{enabled:false},tooltip:{formatter:function(){if(this.key==undefined){return false}return''+this.point.name+": "+this.y+"%
"}},series:[{data:chartopts["data"],colors:chartopts["colors"]}]})};var updateMap=function(results){if(!map){return}bubbles=[];$.each(campaign.results,function(i,result){if(result.latitude==0&&result.longitude==0){return true}newIP=true;$.each(bubbles,function(i,bubble){if(bubble.ip==result.ip){bubbles[i].radius+=1;newIP=false;return false}});if(newIP){bubbles.push({latitude:result.latitude,longitude:result.longitude,name:result.ip,fillKey:"point",radius:2})}});map.bubbles(bubbles)};function createStatusLabel(status,send_date){var label=statuses[status].label||"label-default";var statusColumn=''+status+"";if(status=="Scheduled"||status=="Retrying"){var sendDateMessage="Scheduled to send at "+send_date;statusColumn=''+status+""}return statusColumn}function poll(){api.campaignId.results(campaign.id).success(function(c){campaign=c;var timeline_series_data=[];$.each(campaign.timeline,function(i,event){var event_date=moment.utc(event.time).local();timeline_series_data.push({email:event.email,message:event.message,x:event_date.valueOf(),y:1,marker:{fillColor:statuses[event.message].color}})});var timeline_chart=$("#timeline_chart").highcharts();timeline_chart.series[0].update({data:timeline_series_data});var email_series_data={};Object.keys(statusMapping).forEach(function(k){email_series_data[k]=0});$.each(campaign.results,function(i,result){email_series_data[result.status]++;if(result.reported){email_series_data["Email Reported"]++}var step=progressListing.indexOf(result.status);for(var i=0;i"}return""}return reported},targets:[7]}]});resultsTable.clear();var email_series_data={};var timeline_series_data=[];Object.keys(statusMapping).forEach(function(k){email_series_data[k]=0});$.each(campaign.results,function(i,result){resultsTable.row.add([result.id,'',escapeHtml(result.first_name)||"",escapeHtml(result.last_name)||"",escapeHtml(result.email)||"",escapeHtml(result.position)||"",result.status,result.reported,moment(result.send_date).format("MMMM Do YYYY, h:mm:ss a")]);email_series_data[result.status]++;if(result.reported){email_series_data["Email Reported"]++}var step=progressListing.indexOf(result.status);for(var i=0;i{if(!response.ok){throw new Error(`HTTP error! Status: ${response.status}`)}refresh()}).catch(error=>{let errorMessage=error.message;if(error.message==="Failed to fetch"){errorMessage="This might be due to Mixed Content issues or network problems."}Swal.fire({title:"Error",text:errorMessage,type:"error",confirmButtonText:"Close"})})})}})}$(document).ready(function(){Highcharts.setOptions({global:{useUTC:false}});load();setRefresh=setTimeout(refresh,6e4)}); \ No newline at end of file diff --git a/static/js/src/app/campaign_results.js b/static/js/src/app/campaign_results.js index a16bb13c1..0a198b9db 100644 --- a/static/js/src/app/campaign_results.js +++ b/static/js/src/app/campaign_results.js @@ -935,13 +935,25 @@ function report_mail(rid, cid) { api.campaignId.get(cid).success((function(c) { report_url = new URL(c.url) report_url.pathname = '/report' - report_url.search = "?rid=" + rid - $.ajax({ - url: report_url, - method: "GET", - success: function(data) { - refresh(); + report_url.search = "?rid=" + rid + fetch(report_url) + .then(response => { + if (!response.ok) { + throw new Error(`HTTP error! Status: ${response.status}`); } + refresh(); + }) + .catch(error => { + let errorMessage = error.message; + if (error.message === "Failed to fetch") { + errorMessage = "This might be due to Mixed Content issues or network problems."; + } + Swal.fire({ + title: 'Error', + text: errorMessage, + type: 'error', + confirmButtonText: 'Close' + }); }); })); } diff --git a/templates/sending_profiles.html b/templates/sending_profiles.html index d68cc8671..fd9a3ec83 100644 --- a/templates/sending_profiles.html +++ b/templates/sending_profiles.html @@ -52,7 +52,7 @@ -