diff --git a/app/app.go b/app/app.go index a889434..8344a1b 100644 --- a/app/app.go +++ b/app/app.go @@ -3,8 +3,11 @@ package app import ( "context" "errors" + "fmt" "github.com/go-redis/redis/v8" "github.com/gofiber/fiber/v2" + "github.com/minio/minio-go/v7" + "github.com/minio/minio-go/v7/pkg/credentials" "github.com/skeris/appInit" "github.com/themakers/hlog" "go.uber.org/zap" @@ -67,6 +70,9 @@ type Options struct { SmtpPassword string `env:"SMTP_PASSWORD"` SmtpApiKey string `env:"SMTP_API_KEY"` CustomerServiceAddress string `env:"CUSTOMER_SERVICE_ADDRESS"` + MinioEP string `env:"MINIO_EP" default:"localhost:3002"` + MinioAK string `env:"MINIO_AK" default:"minio"` + MinioSK string `env:"MINIO_SK" default:"miniostorage"` } func New(ctx context.Context, opts interface{}, ver appInit.Version) (appInit.CommonApp, error) { @@ -144,7 +150,16 @@ func New(ctx context.Context, opts interface{}, ver appInit.Version) (appInit.Co } customerServiceClient := customer.NewCustomerServiceClient(customerServiceConn) - pgdal, err := dal.New(ctx, options.PostgresCredentials, nil) + minioClient, err := minio.New(options.MinioEP, &minio.Options{ + Creds: credentials.NewStaticV4(options.MinioAK, options.MinioSK, ""), + Secure: options.IsProd, + }) + if err != nil { + fmt.Println("MINIOERR", options.MinioEP, err) + return nil, err + } + + pgdal, err := dal.New(ctx, options.PostgresCredentials, nil, minioClient) if err != nil { return nil, err } diff --git a/clients/mailclient/client.go b/clients/mailclient/client.go index 876fb6d..96e59e8 100644 --- a/clients/mailclient/client.go +++ b/clients/mailclient/client.go @@ -50,7 +50,9 @@ func NewClient(deps ClientDeps) *Client { } func (c *Client) SendMailWithAttachment(recipient, subject string, emailTemplate string, data EmailTemplateData, attachments []Attachment) error { - text, err := generateTextFromTemplate(data, emailTemplate) + sanitizedData := sanitizeHTMLData(data) + + text, err := generateTextFromTemplate(sanitizedData, emailTemplate) if err != nil { c.deps.Logger.Module("Error generate text from template") return err diff --git a/clients/mailclient/utils.go b/clients/mailclient/utils.go index 3250787..42e0301 100644 --- a/clients/mailclient/utils.go +++ b/clients/mailclient/utils.go @@ -1,12 +1,15 @@ package mailclient import ( + "bytes" "crypto/rand" "encoding/json" "fmt" + "golang.org/x/net/html" "html/template" "io" "penahub.gitlab.yandexcloud.net/backend/quiz/common.git/model" + "strings" ) type LineWriter struct { @@ -79,3 +82,92 @@ func RenderImage(content string) template.HTML { fmt.Println(tpl) return tpl } + +func sanitizeHTMLData(data EmailTemplateData) EmailTemplateData { + sanitized := EmailTemplateData{ + QuizConfig: stripHTMLResultInfo(data.QuizConfig), + AnswerContent: stripHTMLResultContent(data.AnswerContent), + AllAnswers: stripHTMLResultAnswers(data.AllAnswers), + QuestionsMap: stripHTMLResultMap(data.QuestionsMap), + AnswerTime: StripHTML(data.AnswerTime), + } + return sanitized +} + +func stripHTMLResultInfo(input model.ResultInfo) model.ResultInfo { + return model.ResultInfo{ + When: StripHTML(input.When), + Theme: StripHTML(input.Theme), + Reply: StripHTML(input.Reply), + ReplName: StripHTML(input.ReplName), + } +} + +func stripHTMLResultContent(input model.ResultContent) model.ResultContent { + return model.ResultContent{ + Text: StripHTML(input.Text), + Name: StripHTML(input.Name), + Email: StripHTML(input.Email), + Phone: StripHTML(input.Phone), + Address: StripHTML(input.Address), + Telegram: StripHTML(input.Telegram), + Wechat: StripHTML(input.Wechat), + Viber: StripHTML(input.Viber), + Vk: StripHTML(input.Vk), + Skype: StripHTML(input.Skype), + Whatsup: StripHTML(input.Whatsup), + Messenger: StripHTML(input.Messenger), + Custom: stripHTMLCustom(input.Custom), + } +} + +func stripHTMLResultAnswers(answers []model.ResultAnswer) []model.ResultAnswer { + sanitized := make([]model.ResultAnswer, len(answers)) + for i, j := range answers { + sanitized[i] = model.ResultAnswer{ + Content: StripHTML(j.Content), + CreatedAt: j.CreatedAt, + QuestionID: j.QuestionID, + AnswerID: j.AnswerID, + } + } + return sanitized +} + +func stripHTMLResultMap(questionsMap map[uint64]string) map[uint64]string { + sanitized := make(map[uint64]string) + for i, j := range questionsMap { + sanitized[i] = StripHTML(j) + } + return sanitized +} + +func stripHTMLCustom(custom map[string]string) map[string]string { + sanitized := make(map[string]string) + for i, j := range custom { + sanitized[i] = StripHTML(j) + } + return sanitized +} + +func StripHTML(htmlString string) string { + tokenizer := html.NewTokenizer(bytes.NewBufferString(htmlString)) + var result bytes.Buffer + for { + tokenType := tokenizer.Next() + switch tokenType { + case html.ErrorToken: + return strings.TrimSpace(result.String()) + case html.TextToken: + result.WriteString(tokenizer.Token().Data) + result.WriteString("\n") + case html.StartTagToken, html.EndTagToken: + tagName, _ := tokenizer.TagName() + if string(tagName) == "a" { + _, attrVal, _ := tokenizer.TagAttr() + result.WriteString(string(attrVal)) + result.WriteString("\n") + } + } + } +} diff --git a/go.mod b/go.mod index d3d2462..4ba327f 100644 --- a/go.mod +++ b/go.mod @@ -14,7 +14,7 @@ require ( go.uber.org/zap v1.26.0 google.golang.org/grpc v1.61.1 google.golang.org/protobuf v1.32.0 - penahub.gitlab.yandexcloud.net/backend/quiz/common.git v0.0.0-20240327143506-416edf5094db + penahub.gitlab.yandexcloud.net/backend/quiz/common.git v0.0.0-20240328115420-a7f632c44159 ) require ( @@ -26,7 +26,7 @@ require ( github.com/google/uuid v1.6.0 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/go-multierror v1.1.1 // indirect - github.com/klauspost/compress v1.17.4 // indirect + github.com/klauspost/compress v1.17.6 // indirect github.com/lib/pq v1.10.9 // indirect github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.20 // indirect @@ -40,8 +40,8 @@ require ( github.com/valyala/tcplisten v1.0.0 // indirect go.uber.org/atomic v1.7.0 // indirect go.uber.org/multierr v1.10.0 // indirect - golang.org/x/net v0.18.0 // indirect - golang.org/x/sys v0.15.0 // indirect + golang.org/x/net v0.21.0 // indirect + golang.org/x/sys v0.17.0 // indirect golang.org/x/text v0.14.0 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20231106174013-bbf56f31fb17 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect diff --git a/go.sum b/go.sum index dfe9269..24666ec 100644 --- a/go.sum +++ b/go.sum @@ -49,6 +49,7 @@ github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9 github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/klauspost/compress v1.17.4 h1:Ej5ixsIri7BrIjBkRZLTo6ghwrEtHFk7ijlczPW4fZ4= github.com/klauspost/compress v1.17.4/go.mod h1:/dCuZOvVtNoHsyb+cuJD3itjs3NbnF6KH9zAO4BDxPM= +github.com/klauspost/compress v1.17.6/go.mod h1:/dCuZOvVtNoHsyb+cuJD3itjs3NbnF6KH9zAO4BDxPM= github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= @@ -135,6 +136,7 @@ golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.18.0 h1:mIYleuAkSbHh0tCv7RvjL3F6ZVbLjq4+R7zbOn3Kokg= golang.org/x/net v0.18.0/go.mod h1:/czyP5RqHAH4odGYxBJ1qz0+CE5WZ+2j1YgoEo8F2jQ= +golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -142,6 +144,7 @@ golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc= golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= @@ -178,5 +181,7 @@ penahub.gitlab.yandexcloud.net/backend/penahub_common v0.0.0-20240202120244-c4ef penahub.gitlab.yandexcloud.net/backend/penahub_common v0.0.0-20240202120244-c4ef330cfe5d/go.mod h1:lTmpjry+8evVkXWbEC+WMOELcFkRD1lFMc7J09mOndM= penahub.gitlab.yandexcloud.net/backend/quiz/common.git v0.0.0-20240327143506-416edf5094db h1:zSbTQEUxnZAhttiL9WkuX51qxHPEaXGm00Y+WlEnHug= penahub.gitlab.yandexcloud.net/backend/quiz/common.git v0.0.0-20240327143506-416edf5094db/go.mod h1:okduDAq0NVVDcM+TMyrd4mVXzBMeTzYI2B2/yi1sL1Y= +penahub.gitlab.yandexcloud.net/backend/quiz/common.git v0.0.0-20240328115420-a7f632c44159 h1:H//yyZ7KJAdVWByz4hV78TMLTENRE3CiBrJBTaQAo2A= +penahub.gitlab.yandexcloud.net/backend/quiz/common.git v0.0.0-20240328115420-a7f632c44159/go.mod h1:/DcyAjBh41IbomuDu5QzhL9flZW6lWO3ZAEbUXKobk0= penahub.gitlab.yandexcloud.net/backend/quiz/core.git v0.0.0-20240219174804-d78fd38511af h1:jQ7HaXSutDX5iepU7VRImxhikK7lV/lBKkiloOZ4Emo= penahub.gitlab.yandexcloud.net/backend/quiz/core.git v0.0.0-20240219174804-d78fd38511af/go.mod h1:5S5YwjSXWmnEKjBjG6MtyGtFmljjukDRS8CwHk/CF/I= diff --git a/tests/smtp_test.go b/tests/smtp_test.go index e202859..0c8da93 100644 --- a/tests/smtp_test.go +++ b/tests/smtp_test.go @@ -30,33 +30,37 @@ func TestProcessMessageToSMTP(t *testing.T) { client := mailclient.NewClient(clientDeps) - recipient := "sadasdsadsadsafd.dasdsadasdad@mail.ru" + recipient := "pashamullin2001@gmail.com" subject := "Test" data := mailclient.EmailTemplateData{ QuizConfig: model.ResultInfo{ - Theme: "Taemplste Quiz", + Theme: "

Taemplste Quiz

", }, AnswerContent: model.ResultContent{ - Name: "Pasha", - Phone: "+723456789", + Name: "Pasha", + Phone: "
+723456789@test
", + Wechat: "test_wechat", + Viber: "+723456789", + Vk: "test_vk", Skype: "test_skype", Whatsup: "test_whatsup", Messenger: "test_messenger", }, AllAnswers: []model.ResultAnswer{ - {QuestionID: 1, Content: "Pasha"}, - {QuestionID: 2, Content: "From a friend"}, + {AnswerID: 1, QuestionID: 1, Content: "https://www.google.com/search?sca_esv=c51a80de1a7d45f0&sxsrf=ACQVn08xG-a0eH1Vds246-fONoSvvjzVMw:1707762485524&q=ku,n&tbm=isch&source=lnms&sa=X&ved=2ahUKEwi7ub2Ct6aEAxVVb_UHHQIQBVoQ0pQJegQIDRAB&biw=1536&bih=703&dpr=1.25#imgrc=0PWwTuuH2uBQ3M|html", CreatedAt: time.Now()}, + {AnswerID: 2, QuestionID: 2, Content: "From a friend", CreatedAt: time.Now()}, + {AnswerID: 3, QuestionID: 3, Content: "From a friend", CreatedAt: time.Now()}, + {AnswerID: 4, QuestionID: 4, Content: `{"Image":"https://letsenhance.io/static/8f5e523ee6b2479e26ecc91b9c25261e/1015f/MainAfter.jpg","Description":"Gekon"}`, CreatedAt: time.Now()}, }, QuestionsMap: map[uint64]string{ - 1: "How did you hear about us?", + 1: "?", 2: "How did you hear about us?", + 3: "que 3", + 4: "que 4", }, AnswerTime: time.Now().Format("Monday, 2 January 2006 г., 15:04 UTC-07:00"), }