diff --git a/.github/workflows/golangci-lint.yml b/.github/workflows/golangci-lint.yml new file mode 100644 index 0000000..2d0a327 --- /dev/null +++ b/.github/workflows/golangci-lint.yml @@ -0,0 +1,49 @@ +# SPDX-FileCopyrightText: 2022 Winni Neessen +# +# SPDX-License-Identifier: CC0-1.0 + +name: golangci-lint +on: + push: + tags: + - v* + branches: + - main + pull_request: +permissions: + contents: read + # Optional: allow read access to pull request. Use with `only-new-issues` option. + # pull-requests: read +jobs: + golangci: + name: lint + runs-on: ubuntu-latest + steps: + - uses: actions/setup-go@v3 + with: + go-version: 1.19 + - uses: actions/checkout@v3 + - name: golangci-lint + uses: golangci/golangci-lint-action@v3 + with: + # Optional: version of golangci-lint to use in form of v1.2 or v1.2.3 or `latest` to use the latest version + version: latest + + # Optional: working directory, useful for monorepos + # working-directory: somedir + + # Optional: golangci-lint command line arguments. + # args: --issues-exit-code=0 + + # Optional: show only new issues if it's a pull request. The default value is `false`. + # only-new-issues: true + + # Optional: if set to true then the all caching functionality will be complete disabled, + # takes precedence over all other caching options. + # skip-cache: true + + # Optional: if set to true then the action don't cache or restore ~/go/pkg. + # skip-pkg-cache: true + + # Optional: if set to true then the action don't cache or restore ~/.cache/go-build. + # skip-build-cache: true diff --git a/.golangci.toml b/.golangci.toml new file mode 100644 index 0000000..7d1b888 --- /dev/null +++ b/.golangci.toml @@ -0,0 +1,11 @@ +## SPDX-FileCopyrightText: 2022 Winni Neessen +## +## SPDX-License-Identifier: MIT + +[run] +go = "1.16" +tests = true + +[linters] +enable = ["stylecheck", "whitespace", "containedctx", "contextcheck", "decorder", + "errname", "errorlint", "gofmt", "gofumpt"] \ No newline at end of file diff --git a/api/api.go b/api/api.go index ba7b38e..41b2dc8 100644 --- a/api/api.go +++ b/api/api.go @@ -1,7 +1,7 @@ package api import ( - "github.com/ReneKroon/ttlcache/v2" + "github.com/jellydator/ttlcache/v2" "github.com/wneessen/js-mailer/config" ) diff --git a/api/form.go b/api/form.go index 3740753..b0c4232 100644 --- a/api/form.go +++ b/api/form.go @@ -1,8 +1,10 @@ package api import ( + "errors" "fmt" - "github.com/ReneKroon/ttlcache/v2" + + "github.com/jellydator/ttlcache/v2" "github.com/wneessen/js-mailer/form" ) @@ -11,7 +13,7 @@ import ( func (r *Route) GetForm(i string) (form.Form, error) { var formObj form.Form cacheForm, err := r.Cache.Get(fmt.Sprintf("formObj_%s", i)) - if err != nil && err != ttlcache.ErrNotFound { + if err != nil && !errors.Is(err, ttlcache.ErrNotFound) { return formObj, err } if cacheForm != nil { @@ -21,7 +23,7 @@ func (r *Route) GetForm(i string) (form.Form, error) { if err != nil { return formObj, err } - if err := r.Cache.Set(fmt.Sprintf("formObj_%s", formObj.Id), formObj); err != nil { + if err := r.Cache.Set(fmt.Sprintf("formObj_%s", formObj.ID), formObj); err != nil { return formObj, err } } diff --git a/api/ping.go b/api/ping.go index a957603..b0d80a3 100644 --- a/api/ping.go +++ b/api/ping.go @@ -1,8 +1,9 @@ package api import ( - "github.com/labstack/echo/v4" "net/http" + + "github.com/labstack/echo/v4" ) // PingResponse reflects the JSON structure for a ping response diff --git a/api/sendform.go b/api/sendform.go index c200900..e19e328 100644 --- a/api/sendform.go +++ b/api/sendform.go @@ -2,17 +2,18 @@ package api import ( "fmt" + "net/http" + "time" + "github.com/labstack/echo/v4" "github.com/wneessen/go-mail" "github.com/wneessen/js-mailer/form" "github.com/wneessen/js-mailer/response" - "net/http" - "time" ) // SentSuccessful represents confirmation JSON structure for a successfully sent message type SentSuccessful struct { - FormId string `json:"form_id"` + FormID string `json:"form_id"` SendTime int64 `json:"send_time"` ConfirmationSent bool `json:"confirmation_sent"` ConfirmationRcpt string `json:"confirmation_rcpt"` @@ -112,7 +113,7 @@ func (r *Route) SendForm(c echo.Context) error { StatusCode: http.StatusOK, Status: http.StatusText(http.StatusOK), Data: SentSuccessful{ - FormId: sr.FormObj.Id, + FormID: sr.FormObj.ID, SendTime: time.Now().Unix(), ConfirmationSent: confirmWasSent, ConfirmationRcpt: confirmRcpt, @@ -151,7 +152,6 @@ func GetMailClient(f *form.Form) (*mail.Client, error) { mc, err := mail.NewClient(f.Server.Host, mail.WithPort(f.Server.Port), mail.WithUsername(f.Server.Username), mail.WithPassword(f.Server.Password), mail.WithSMTPAuth(mail.SMTPAuthPlain), mail.WithTimeout(serverTimeout)) - if err != nil { return mc, err } diff --git a/api/sendform_mw.go b/api/sendform_mw.go index 5ca1651..32aca01 100644 --- a/api/sendform_mw.go +++ b/api/sendform_mw.go @@ -4,13 +4,14 @@ import ( "bytes" "crypto/sha256" "encoding/json" + "errors" "fmt" "net/http" "net/url" "regexp" "strings" - "github.com/ReneKroon/ttlcache/v2" + "github.com/jellydator/ttlcache/v2" "github.com/labstack/echo/v4" "github.com/wneessen/js-mailer/form" "github.com/wneessen/js-mailer/response" @@ -18,7 +19,7 @@ import ( // SendFormRequest reflects the structure of the send form request data type SendFormRequest struct { - FormId string `param:"fid"` + FormID string `param:"fid"` FormObj *form.Form Token string `param:"token"` TokenResp *TokenResponse @@ -56,21 +57,23 @@ func (r *Route) SendFormBindForm(next echo.HandlerFunc) echo.HandlerFunc { // Let's retrieve the formObj from cache cacheObj, err := r.Cache.Get(sr.Token) - if err == ttlcache.ErrNotFound { - return echo.NewHTTPError(http.StatusNotFound, "not a valid send URL") - } - if err != nil && err != ttlcache.ErrNotFound { - c.Logger().Errorf("failed to look up token in cache: %s", err) - return echo.NewHTTPError(http.StatusInternalServerError, &response.ErrorObj{ - Message: "failed to look up token in cache", - Data: err.Error(), - }) + if err != nil { + switch { + case errors.Is(err, ttlcache.ErrNotFound): + return echo.NewHTTPError(http.StatusNotFound, "not a valid send URL") + case !errors.Is(err, ttlcache.ErrNotFound): + c.Logger().Errorf("failed to look up token in cache: %s", err) + return echo.NewHTTPError(http.StatusInternalServerError, &response.ErrorObj{ + Message: "failed to look up token in cache", + Data: err.Error(), + }) + } } if cacheObj != nil { TokenRespObj := cacheObj.(TokenResponse) sr.TokenResp = &TokenRespObj } - if sr.TokenResp != nil && sr.TokenResp.FormId != sr.FormId { + if sr.TokenResp != nil && sr.TokenResp.FormID != sr.FormID { c.Logger().Warn("URL form id does not match the cached form object id") return echo.NewHTTPError(http.StatusBadRequest, "invalid form id") } @@ -81,7 +84,7 @@ func (r *Route) SendFormBindForm(next echo.HandlerFunc) echo.HandlerFunc { }() // Let's try to read formobj from cache - formObj, err := r.GetForm(sr.FormId) + formObj, err := r.GetForm(sr.FormID) if err != nil { c.Logger().Errorf("failed get form object: %s", err) return echo.NewHTTPError(http.StatusInternalServerError, "form lookup failed") @@ -312,7 +315,7 @@ func (r *Route) SendFormCheckToken(next echo.HandlerFunc) echo.HandlerFunc { return echo.NewHTTPError(http.StatusUnauthorized, "domain not allowed to access form") } tokenText := fmt.Sprintf("%s_%d_%d_%s_%s", reqOrigin, sr.TokenResp.CreateTime, - sr.TokenResp.ExpireTime, sr.FormObj.Id, sr.FormObj.Secret) + sr.TokenResp.ExpireTime, sr.FormObj.ID, sr.FormObj.Secret) tokenSha := fmt.Sprintf("%x", sha256.Sum256([]byte(tokenText))) if tokenSha != sr.Token { c.Logger().Errorf("security token does not match") diff --git a/api/token.go b/api/token.go index ca199a4..4724915 100644 --- a/api/token.go +++ b/api/token.go @@ -3,25 +3,26 @@ package api import ( "crypto/sha256" "fmt" - "github.com/labstack/echo/v4" - "github.com/wneessen/js-mailer/response" "net/http" "net/url" "time" + + "github.com/labstack/echo/v4" + "github.com/wneessen/js-mailer/response" ) // TokenRequest reflects the incoming gettoken request data that for the parameter binding type TokenRequest struct { - FormId string `query:"formid" form:"formid"` + FormID string `query:"formid" form:"formid"` } // TokenResponse reflects the JSON response struct for token request type TokenResponse struct { Token string `json:"token"` - FormId string `json:"form_id"` + FormID string `json:"form_id"` CreateTime int64 `json:"create_time,omitempty"` ExpireTime int64 `json:"expire_time,omitempty"` - Url string `json:"url"` + URL string `json:"url"` EncType string `json:"enc_type"` Method string `json:"method"` } @@ -36,7 +37,7 @@ func (r *Route) GetToken(c echo.Context) error { } // Let's try to read formobj from cache - formObj, err := r.GetForm(fr.FormId) + formObj, err := r.GetForm(fr.FormID) if err != nil { c.Logger().Errorf("failed to get form object: %s", err) return echo.NewHTTPError(http.StatusInternalServerError, &response.ErrorObj{ @@ -60,7 +61,7 @@ func (r *Route) GetToken(c echo.Context) error { } } if !isValid { - c.Logger().Errorf("domain %q not in allowed domains list for form %s", reqOrigin, formObj.Id) + c.Logger().Errorf("domain %q not in allowed domains list for form %s", reqOrigin, formObj.ID) return echo.NewHTTPError(http.StatusUnauthorized, "domain is not authorized to access the requested form") } @@ -74,15 +75,15 @@ func (r *Route) GetToken(c echo.Context) error { nowTime := time.Now() expTime := time.Now().Add(time.Minute * 10) tokenText := fmt.Sprintf("%s_%d_%d_%s_%s", reqOrigin, nowTime.Unix(), expTime.Unix(), - formObj.Id, formObj.Secret) + formObj.ID, formObj.Secret) tokenSha := fmt.Sprintf("%x", sha256.Sum256([]byte(tokenText))) respToken := TokenResponse{ Token: tokenSha, - FormId: formObj.Id, + FormID: formObj.ID, CreateTime: nowTime.Unix(), ExpireTime: expTime.Unix(), - Url: fmt.Sprintf("%s://%s/api/v1/send/%s/%s", reqScheme, - c.Request().Host, url.QueryEscape(formObj.Id), url.QueryEscape(tokenSha)), + URL: fmt.Sprintf("%s://%s/api/v1/send/%s/%s", reqScheme, + c.Request().Host, url.QueryEscape(formObj.ID), url.QueryEscape(tokenSha)), EncType: "multipart/form-data", Method: "post", } diff --git a/config/config.go b/config/config.go index 9227718..c23eed6 100644 --- a/config/config.go +++ b/config/config.go @@ -2,11 +2,12 @@ package config import ( "fmt" - "github.com/kkyr/fig" "log" "os" "path/filepath" "time" + + "github.com/kkyr/fig" ) // Config represents the global config object struct diff --git a/form/form.go b/form/form.go index 9f04e4b..81e45be 100644 --- a/form/form.go +++ b/form/form.go @@ -2,10 +2,11 @@ package form import ( "fmt" + "os" + "github.com/cyphar/filepath-securejoin" "github.com/kkyr/fig" "github.com/wneessen/js-mailer/config" - "os" ) // Form reflect the configuration struct for form configurations @@ -21,7 +22,7 @@ type Form struct { Content string `fig:"content"` } Domains []string `fig:"domains" validate:"required"` - Id string `fig:"id" validate:"required"` + ID string `fig:"id" validate:"required"` Recipients []string `fig:"recipients" validate:"required"` ReplyTo struct { Field string `json:"field"` @@ -67,12 +68,12 @@ func NewForm(c *config.Config, i string) (Form, error) { } _, err = os.Stat(formPath) if err != nil { - return Form{}, fmt.Errorf("failed to stat form config: %s", err) + return Form{}, fmt.Errorf("failed to stat form config: %w", err) } var formObj Form if err := fig.Load(&formObj, fig.File(fmt.Sprintf("%s.json", i)), fig.Dirs(c.Forms.Path)); err != nil { - return Form{}, fmt.Errorf("failed to read form config: %s", err) + return Form{}, fmt.Errorf("failed to read form config: %w", err) } return formObj, nil diff --git a/go.mod b/go.mod index a551fb0..982aa11 100644 --- a/go.mod +++ b/go.mod @@ -3,11 +3,17 @@ module github.com/wneessen/js-mailer go 1.16 require ( - github.com/ReneKroon/ttlcache/v2 v2.11.0 github.com/cyphar/filepath-securejoin v0.2.3 + github.com/jellydator/ttlcache/v2 v2.11.1 github.com/kkyr/fig v0.3.0 github.com/labstack/echo/v4 v4.9.1 github.com/labstack/gommon v0.4.0 + github.com/mattn/go-colorable v0.1.13 // indirect + github.com/mitchellh/mapstructure v1.5.0 // indirect + github.com/pelletier/go-toml v1.9.5 // indirect + github.com/valyala/fasttemplate v1.2.2 // indirect github.com/wneessen/go-mail v0.3.4 + golang.org/x/crypto v0.2.0 // indirect + golang.org/x/sync v0.1.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index 41d22af..5367a85 100644 --- a/go.sum +++ b/go.sum @@ -1,5 +1,3 @@ -github.com/ReneKroon/ttlcache/v2 v2.11.0 h1:OvlcYFYi941SBN3v9dsDcC2N8vRxyHcCmJb3Vl4QMoM= -github.com/ReneKroon/ttlcache/v2 v2.11.0/go.mod h1:mBxvsNY+BT8qLLd6CuAJubbKo6r0jh3nb5et22bbfGY= github.com/cyphar/filepath-securejoin v0.2.3 h1:YX6ebbZCZP7VkM3scTTokDgBL2TY741X51MTk3ycuNI= github.com/cyphar/filepath-securejoin v0.2.3/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -7,6 +5,8 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY= github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I= +github.com/jellydator/ttlcache/v2 v2.11.1 h1:AZGME43Eh2Vv3giG6GeqeLeFXxwxn1/qHItqWZl6U64= +github.com/jellydator/ttlcache/v2 v2.11.1/go.mod h1:RtE5Snf0/57e+2cLWFYWCCsLas2Hy3c5Z4n14XmSvTI= github.com/kkyr/fig v0.3.0 h1:5bd1amYKp/gsK2bGEUJYzcCrQPKOZp6HZD9K21v9Guo= github.com/kkyr/fig v0.3.0/go.mod h1:fEnrLjwg/iwSr8ksJF4DxrDmCUir5CaVMLORGYMcz30= github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= @@ -18,14 +18,18 @@ github.com/labstack/echo/v4 v4.9.1 h1:GliPYSpzGKlyOhqIbG8nmHBo3i1saKWFOgh41AN3b+ github.com/labstack/echo/v4 v4.9.1/go.mod h1:Pop5HLc+xoc4qhTZ1ip6C0RtP7Z+4VzRLWZZFKqbbjo= github.com/labstack/gommon v0.4.0 h1:y7cvthEAEbU0yHOf4axH8ZG2NH8knB9iNSoTO8dyIk8= github.com/labstack/gommon v0.4.0/go.mod h1:uW6kP17uPlLJsD3ijUYn3/M5bAxtlZhMI6m3MFxTMTM= -github.com/mattn/go-colorable v0.1.11 h1:nQ+aFkoE2TMGc0b68U2OKSexC+eq46+XwZzWXHRmPYs= github.com/mattn/go-colorable v0.1.11/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= -github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y= +github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= +github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= -github.com/mitchellh/mapstructure v1.4.1 h1:CpVNEelQCZBooIPDn+AR3NpivK/TIKU8bDxdASFVQag= +github.com/mattn/go-isatty v0.0.16 h1:bq3VjFmv/sOjHtdEhmkEV4x1AJtvUvOJ2PFAZ5+peKQ= +github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= -github.com/pelletier/go-toml v1.9.3 h1:zeC5b1GviRUyKYd6OJPvBU/mcVDVoL1OhT17FCt5dSQ= +github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= +github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/pelletier/go-toml v1.9.3/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= +github.com/pelletier/go-toml v1.9.5 h1:4yBQzkHv+7BHq2PQUZF3Mx0IYxG7LsP222s7Agd3ve8= +github.com/pelletier/go-toml v1.9.5/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= @@ -34,34 +38,43 @@ github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5Cc github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= -github.com/valyala/fasttemplate v1.2.1 h1:TVEnxayobAdVkhQfrfes2IzOB6o+z4roRkPF52WA1u4= github.com/valyala/fasttemplate v1.2.1/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ= +github.com/valyala/fasttemplate v1.2.2 h1:lxLXG0uE3Qnshl9QyaK6XJxMXlQZELvChBOCmQD0Loo= +github.com/valyala/fasttemplate v1.2.2/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ= github.com/wneessen/go-mail v0.3.4 h1:75G6lojt3CxwSq73csMduxF7DJ3hLF2s2KJXJVDOr0k= github.com/wneessen/go-mail v0.3.4/go.mod h1:m25lkU2GYQnlVr6tdwK533/UXxo57V0kLOjaFYmub0E= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= go.uber.org/goleak v1.1.10 h1:z+mqJhf6ss6BSfSM671tgKyZBFPTTJM+HLxnhPC3wu0= go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20210817164053-32db794688a5 h1:HWj/xjIHfjYU5nVXpTM0s39J9CbLn7Cc5a7IC5rwsMQ= golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.2.0 h1:BRXPfhNivWL5Yq0BGQ39a2sW6t44aODpfxkWjYdzewE= +golang.org/x/crypto v0.2.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5 h1:2M3HP5CCK1Si9FQhwnzYhXdG6DXeebvUHFpre8QvbyI= golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f h1:OfiFi4JbukWwe3lzw+xunroH1mnC1e2Gy5cxNJApiSY= golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.2.0 h1:sZfSu1wtKLGlWI4ZZayP0ck9Y73K1ynO6gqzTdBVdPU= +golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20210220032951-036812b2e83c h1:5KslGYwFpkhGh+Q16bwMP3cOontH8FOep7tGV86Y7SQ= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o= +golang.org/x/sync v0.1.0/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= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -70,14 +83,21 @@ golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211103235746-7861aae1554b h1:1VkfZQv42XQlA/jchYumAnv1UPo6RgF9rJFkTgZIxO4= golang.org/x/sys v0.0.0-20211103235746-7861aae1554b/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.2.0 h1:ljd4t30dBnAvMZaQCevtY0xLLD0A+bRZXbgLMLU1F/A= +golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.4.0 h1:BrVqGRd7+k1DiOgtnFvAkoQEWQvBc25ouMJM6429SFg= +golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/time v0.0.0-20201208040808-7e3f01d25324 h1:Hir2P/De0WpUhtrKGGjvSb2YxUgyZ7EFOSLIcSSpiwE= golang.org/x/time v0.0.0-20201208040808-7e3f01d25324/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -85,8 +105,9 @@ golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3 golang.org/x/tools v0.0.0-20191108193012-7d206e10da11/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20210112230658-8b4aab62c064 h1:BmCFkEH4nJrYcAc2L08yX5RhYGD4j58PTMkEUDkpz2I= golang.org/x/tools v0.0.0-20210112230658-8b4aab62c064/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.1.12 h1:VveCTK38A2rkS8ZqFY25HIDFscX5X9OoEhJd3quQmXU= +golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= diff --git a/main.go b/main.go index dbc3301..589e184 100644 --- a/main.go +++ b/main.go @@ -2,11 +2,12 @@ package main import ( "fmt" - "github.com/ReneKroon/ttlcache/v2" - "github.com/wneessen/js-mailer/config" - "github.com/wneessen/js-mailer/server" "os" "time" + + "github.com/jellydator/ttlcache/v2" + "github.com/wneessen/js-mailer/config" + "github.com/wneessen/js-mailer/server" ) func main() { diff --git a/response/error.go b/response/error.go index 3d3393e..c351243 100644 --- a/response/error.go +++ b/response/error.go @@ -1,8 +1,10 @@ package response import ( - "github.com/labstack/echo/v4" + "errors" "net/http" + + "github.com/labstack/echo/v4" ) // ErrorObj is the structure of an error @@ -24,7 +26,8 @@ func CustomError(err error, c echo.Context) { errResp := &ErrorResponse{ StatusCode: http.StatusInternalServerError, } - if he, ok := err.(*echo.HTTPError); ok { + var he *echo.HTTPError + if errors.As(err, &he) { errResp.StatusCode = he.Code errResp.Status = http.StatusText(errResp.StatusCode) if em, ok := he.Message.(*echo.HTTPError); ok { diff --git a/server/router_api.go b/server/router_api.go index 1558719..0c92e10 100644 --- a/server/router_api.go +++ b/server/router_api.go @@ -4,8 +4,8 @@ import ( "github.com/wneessen/js-mailer/api" ) -// RouterApi registers the JSON API routes with echo -func (s *Srv) RouterApi() { +// RouterAPI registers the JSON API routes with echo +func (s *Srv) RouterAPI() { apiRoute := api.Route{ Cache: s.Cache, Config: s.Config, diff --git a/server/server.go b/server/server.go index 788edad..c95a9a8 100644 --- a/server/server.go +++ b/server/server.go @@ -2,14 +2,16 @@ package server import ( "context" + "errors" "fmt" - "github.com/wneessen/js-mailer/response" "net/http" "os" "os/signal" "time" - "github.com/ReneKroon/ttlcache/v2" + "github.com/wneessen/js-mailer/response" + + "github.com/jellydator/ttlcache/v2" "github.com/labstack/echo/v4" "github.com/labstack/echo/v4/middleware" "github.com/labstack/gommon/log" @@ -17,7 +19,7 @@ import ( ) // VERSION is the global version string contstant -const VERSION = "0.2.7" +const VERSION = "0.2.9" // Srv represents the server object type Srv struct { @@ -41,7 +43,7 @@ func (s *Srv) Start() { s.LogLevel() // Register routes - s.RouterApi() + s.RouterAPI() // Middlewares s.Echo.Use(middleware.Recover()) @@ -54,7 +56,7 @@ func (s *Srv) Start() { s.Echo.Logger.Infof("Starting js-mailer v%s on: %s", VERSION, fmt.Sprintf("%s:%d", s.Config.Server.Addr, s.Config.Server.Port)) err := s.Echo.Start(fmt.Sprintf("%s:%d", s.Config.Server.Addr, s.Config.Server.Port)) - if err != nil && err != http.ErrServerClosed { + if err != nil && !errors.Is(err, http.ErrServerClosed) { s.Echo.Logger.Errorf("Failed to start up web service: %s", err) os.Exit(1) }