New user that wants to receive newsletter can be registered to listmonk
continuous-integration/drone/push Build is passing Details

This commit is contained in:
nemunaire 2023-11-19 14:18:56 +01:00
parent 972c3c7df5
commit e3d8f32b58
7 changed files with 191 additions and 21 deletions

View File

@ -60,7 +60,7 @@ steps:
- sed -i '/npm run build/d' ui/assets.go
- go install github.com/swaggo/swag/cmd/swag@latest
- go generate -v ./...
- go build -v -tags netgo,swagger,ui -ldflags '-w -X "main.Version=${DRONE_BRANCH}-${DRONE_COMMIT}" -X main.build=${DRONE_BUILD_NUMBER}' -o happydomain-${DRONE_STAGE_OS}-${DRONE_STAGE_ARCH}
- go build -v -tags listmonk,netgo,swagger,ui -ldflags '-w -X "main.Version=${DRONE_BRANCH}-${DRONE_COMMIT}" -X main.build=${DRONE_BUILD_NUMBER}' -o happydomain-${DRONE_STAGE_OS}-${DRONE_STAGE_ARCH}
- ln happydomain-${DRONE_STAGE_OS}-${DRONE_STAGE_ARCH} happydomain
environment:
CGO_ENABLED: 0
@ -76,7 +76,7 @@ steps:
- sed -i '/npm run build/d' ui/assets.go
- go install github.com/swaggo/swag/cmd/swag@latest
- go generate -v ./...
- go build -v -tags netgo,swagger,ui -ldflags '-w -X main.Version=${DRONE_TAG##v} -X main.build=${DRONE_BUILD_NUMBER}' -o happydomain-${DRONE_STAGE_OS}-${DRONE_STAGE_ARCH}
- go build -v -tags listmonk,netgo,swagger,ui -ldflags '-w -X main.Version=${DRONE_TAG##v} -X main.build=${DRONE_BUILD_NUMBER}' -o happydomain-${DRONE_STAGE_OS}-${DRONE_STAGE_ARCH}
- ln happydomain-${DRONE_STAGE_OS}-${DRONE_STAGE_ARCH} happydomain
environment:
CGO_ENABLED: 0
@ -132,7 +132,7 @@ steps:
image: golang:1-alpine
commands:
- apk add --no-cache git
- go build -v -tags netgo,swagger,ui -ldflags '-w -X "main.Version=${DRONE_BRANCH}-${DRONE_COMMIT}" -X main.build=${DRONE_BUILD_NUMBER}' -o happydomain-darwin-${DRONE_STAGE_ARCH}
- go build -v -tags listmonk,netgo,swagger,ui -ldflags '-w -X "main.Version=${DRONE_BRANCH}-${DRONE_COMMIT}" -X main.build=${DRONE_BUILD_NUMBER}' -o happydomain-darwin-${DRONE_STAGE_ARCH}
environment:
CGO_ENABLED: 0
GOOS: darwin
@ -146,7 +146,7 @@ steps:
image: golang:1-alpine
commands:
- apk add --no-cache git
- go build -v -tags netgo,swagger,ui -ldflags '-w -X "main.Version=${DRONE_TAG##v}" -X main.build=${DRONE_BUILD_NUMBER}' -o happydomain-darwin-${DRONE_STAGE_ARCH}
- go build -v -tags listmonk,netgo,swagger,ui -ldflags '-w -X "main.Version=${DRONE_TAG##v}" -X main.build=${DRONE_BUILD_NUMBER}' -o happydomain-darwin-${DRONE_STAGE_ARCH}
environment:
CGO_ENABLED: 0
GOOS: darwin
@ -232,7 +232,7 @@ steps:
- sed -i '/npm run build/d' ui/assets.go
- go install github.com/swaggo/swag/cmd/swag@latest
- go generate -v ./...
- go build -v -tags netgo,swagger,ui -ldflags '-w -X "main.Version=${DRONE_BRANCH}-${DRONE_COMMIT}" -X main.build=${DRONE_BUILD_NUMBER}' -o happydomain-${DRONE_STAGE_OS}-${DRONE_STAGE_ARCH}
- go build -v -tags listmonk,netgo,swagger,ui -ldflags '-w -X "main.Version=${DRONE_BRANCH}-${DRONE_COMMIT}" -X main.build=${DRONE_BUILD_NUMBER}' -o happydomain-${DRONE_STAGE_OS}-${DRONE_STAGE_ARCH}
- ln happydomain-${DRONE_STAGE_OS}-${DRONE_STAGE_ARCH} happydomain
environment:
CGO_ENABLED: 0
@ -248,7 +248,7 @@ steps:
- sed -i '/npm run build/d' ui/assets.go
- go install github.com/swaggo/swag/cmd/swag@latest
- go generate -v ./...
- go build -v -tags netgo,swagger,ui -ldflags '-w -X main.Version=${DRONE_TAG##v} -X main.build=${DRONE_BUILD_NUMBER}' -o happydomain-${DRONE_STAGE_OS}-${DRONE_STAGE_ARCH}
- go build -v -tags listmonk,netgo,swagger,ui -ldflags '-w -X main.Version=${DRONE_TAG##v} -X main.build=${DRONE_BUILD_NUMBER}' -o happydomain-${DRONE_STAGE_OS}-${DRONE_STAGE_ARCH}
- ln happydomain-${DRONE_STAGE_OS}-${DRONE_STAGE_ARCH} happydomain
environment:
CGO_ENABLED: 0
@ -295,7 +295,7 @@ steps:
image: golang:1-alpine
commands:
- apk add --no-cache git
- go build -v -tags netgo,swagger,ui -ldflags '-w -X "main.Version=${DRONE_BRANCH}-${DRONE_COMMIT}" -X main.build=${DRONE_BUILD_NUMBER}' -o happydomain-darwin-${DRONE_STAGE_ARCH}
- go build -v -tags listmonk,netgo,swagger,ui -ldflags '-w -X "main.Version=${DRONE_BRANCH}-${DRONE_COMMIT}" -X main.build=${DRONE_BUILD_NUMBER}' -o happydomain-darwin-${DRONE_STAGE_ARCH}
environment:
CGO_ENABLED: 0
GOOS: darwin
@ -309,7 +309,7 @@ steps:
image: golang:1-alpine
commands:
- apk add --no-cache git
- go build -v -tags netgo,swagger,ui -ldflags '-w -X "main.Version=${DRONE_TAG##v}" -X main.build=${DRONE_BUILD_NUMBER}' -o happydomain-darwin-${DRONE_STAGE_ARCH}
- go build -v -tags listmonk,netgo,swagger,ui -ldflags '-w -X "main.Version=${DRONE_TAG##v}" -X main.build=${DRONE_BUILD_NUMBER}' -o happydomain-darwin-${DRONE_STAGE_ARCH}
environment:
CGO_ENABLED: 0
GOOS: darwin
@ -395,7 +395,7 @@ steps:
- sed -i '/npm run build/d' ui/assets.go
- go install github.com/swaggo/swag/cmd/swag@latest
- go generate -v ./...
- go build -v -tags netgo,swagger,ui -ldflags '-w -X "main.Version=${DRONE_BRANCH}-${DRONE_COMMIT}" -X main.build=${DRONE_BUILD_NUMBER}' -o happydomain-${DRONE_STAGE_OS}-${DRONE_STAGE_ARCH}el
- go build -v -tags listmonk,netgo,swagger,ui -ldflags '-w -X "main.Version=${DRONE_BRANCH}-${DRONE_COMMIT}" -X main.build=${DRONE_BUILD_NUMBER}' -o happydomain-${DRONE_STAGE_OS}-${DRONE_STAGE_ARCH}el
environment:
CGO_ENABLED: 0
GOARM: 5
@ -414,7 +414,7 @@ steps:
- sed -i '/npm run build/d' ui/assets.go
- go install github.com/swaggo/swag/cmd/swag@latest
- go generate -v ./...
- go build -v -tags netgo,swagger,ui -ldflags '-w -X "main.Version=${DRONE_TAG##v}" -X main.build=${DRONE_BUILD_NUMBER}' -o happydomain-${DRONE_STAGE_OS}-${DRONE_STAGE_ARCH}el
- go build -v -tags listmonk,netgo,swagger,ui -ldflags '-w -X "main.Version=${DRONE_TAG##v}" -X main.build=${DRONE_BUILD_NUMBER}' -o happydomain-${DRONE_STAGE_OS}-${DRONE_STAGE_ARCH}el
environment:
CGO_ENABLED: 0
GOARM: 5
@ -461,7 +461,7 @@ steps:
image: golang:1-alpine
commands:
- apk --no-cache add build-base git
- go build -v -tags netgo,swagger,ui -ldflags '-w -X "main.Version=${DRONE_BRANCH}-${DRONE_COMMIT}" -X main.build=${DRONE_BUILD_NUMBER}' -o happydomain-${DRONE_STAGE_OS}-${DRONE_STAGE_ARCH}hf
- go build -v -tags listmonk,netgo,swagger,ui -ldflags '-w -X "main.Version=${DRONE_BRANCH}-${DRONE_COMMIT}" -X main.build=${DRONE_BUILD_NUMBER}' -o happydomain-${DRONE_STAGE_OS}-${DRONE_STAGE_ARCH}hf
environment:
CGO_ENABLED: 0
GOARM: 6
@ -477,7 +477,7 @@ steps:
image: golang:1-alpine
commands:
- apk --no-cache add build-base git
- go build -v -tags netgo,swagger,ui -ldflags '-w -X "main.Version=${DRONE_TAG##v}" -X main.build=${DRONE_BUILD_NUMBER}' -o happydomain-${DRONE_STAGE_OS}-${DRONE_STAGE_ARCH}hf
- go build -v -tags listmonk,netgo,swagger,ui -ldflags '-w -X "main.Version=${DRONE_TAG##v}" -X main.build=${DRONE_BUILD_NUMBER}' -o happydomain-${DRONE_STAGE_OS}-${DRONE_STAGE_ARCH}hf
environment:
CGO_ENABLED: 0
GOARM: 6
@ -527,7 +527,7 @@ steps:
- "[ -f docs/docs.go ] || sed -i '/npm run build/d' ui/assets.go"
- "[ -f docs/docs.go ] || go install github.com/swaggo/swag/cmd/swag@latest"
- "[ -f docs/docs.go ] || go generate -v ./..."
- go build -v -tags netgo,swagger,ui -ldflags '-w -X "main.Version=${DRONE_BRANCH}-${DRONE_COMMIT}" -X main.build=${DRONE_BUILD_NUMBER}' -o happydomain-${DRONE_STAGE_OS}-${DRONE_STAGE_ARCH}v7
- go build -v -tags listmonk,netgo,swagger,ui -ldflags '-w -X "main.Version=${DRONE_BRANCH}-${DRONE_COMMIT}" -X main.build=${DRONE_BUILD_NUMBER}' -o happydomain-${DRONE_STAGE_OS}-${DRONE_STAGE_ARCH}v7
- ln happydomain-${DRONE_STAGE_OS}-${DRONE_STAGE_ARCH}v7 happydomain
environment:
CGO_ENABLED: 0
@ -541,7 +541,7 @@ steps:
image: golang:1-alpine
commands:
- apk --no-cache add build-base git
- go build -v -tags netgo,swagger,ui -ldflags '-w -X "main.Version=${DRONE_TAG##v}" -X main.build=${DRONE_BUILD_NUMBER}' -o happydomain-${DRONE_STAGE_OS}-${DRONE_STAGE_ARCH}v7
- go build -v -tags listmonk,netgo,swagger,ui -ldflags '-w -X "main.Version=${DRONE_TAG##v}" -X main.build=${DRONE_BUILD_NUMBER}' -o happydomain-${DRONE_STAGE_OS}-${DRONE_STAGE_ARCH}v7
- ln happydomain-${DRONE_STAGE_OS}-${DRONE_STAGE_ARCH}v7 happydomain
environment:
CGO_ENABLED: 0

View File

@ -59,7 +59,7 @@ go generate ./...
3. Finaly, build the Go code:
```
go build -tags swagger,ui
go build -tags listmonk,swagger,ui
```
This last command will create a binary `happyDomain` you can use standalone.

43
actions/newsletter.go Normal file
View File

@ -0,0 +1,43 @@
// Copyright or © or Copr. happyDNS (2023)
//
// contact@happydomain.org
//
// This software is a computer program whose purpose is to provide a modern
// interface to interact with DNS systems.
//
// This software is governed by the CeCILL license under French law and abiding
// by the rules of distribution of free software. You can use, modify and/or
// redistribute the software under the terms of the CeCILL license as
// circulated by CEA, CNRS and INRIA at the following URL
// "http://www.cecill.info".
//
// As a counterpart to the access to the source code and rights to copy, modify
// and redistribute granted by the license, users are provided only with a
// limited warranty and the software's author, the holder of the economic
// rights, and the successive licensors have only limited liability.
//
// In this respect, the user's attention is drawn to the risks associated with
// loading, using, modifying and/or developing or reproducing the software by
// the user in light of its specific status of free software, that may mean
// that it is complicated to manipulate, and that also therefore means that it
// is reserved for developers and experienced professionals having in-depth
// computer knowledge. Users are therefore encouraged to load and test the
// software's suitability as regards their requirements in conditions enabling
// the security of their systems and/or data to be ensured and, more generally,
// to use and operate it in the same conditions as regards security.
//
// The fact that you are presently reading this means that you have had
// knowledge of the CeCILL license and that you accept its terms.
//go:build !listmonk
package actions
import (
"git.happydns.org/happyDomain/model"
)
func SubscribeToNewsletter(u *happydns.User) error {
// Do nothing
return nil
}

View File

@ -0,0 +1,116 @@
// Copyright or © or Copr. happyDNS (2023)
//
// contact@happydomain.org
//
// This software is a computer program whose purpose is to provide a modern
// interface to interact with DNS systems.
//
// This software is governed by the CeCILL license under French law and abiding
// by the rules of distribution of free software. You can use, modify and/or
// redistribute the software under the terms of the CeCILL license as
// circulated by CEA, CNRS and INRIA at the following URL
// "http://www.cecill.info".
//
// As a counterpart to the access to the source code and rights to copy, modify
// and redistribute granted by the license, users are provided only with a
// limited warranty and the software's author, the holder of the economic
// rights, and the successive licensors have only limited liability.
//
// In this respect, the user's attention is drawn to the risks associated with
// loading, using, modifying and/or developing or reproducing the software by
// the user in light of its specific status of free software, that may mean
// that it is complicated to manipulate, and that also therefore means that it
// is reserved for developers and experienced professionals having in-depth
// computer knowledge. Users are therefore encouraged to load and test the
// software's suitability as regards their requirements in conditions enabling
// the security of their systems and/or data to be ensured and, more generally,
// to use and operate it in the same conditions as regards security.
//
// The fact that you are presently reading this means that you have had
// knowledge of the CeCILL license and that you accept its terms.
//go:build listmonk
package actions
import (
"bytes"
"encoding/json"
"flag"
"fmt"
"log"
"net/http"
"path/filepath"
"git.happydns.org/happyDomain/config"
"git.happydns.org/happyDomain/model"
)
var (
ListmonkURL config.URL
ListmonkId int
)
type ListmonkSubscriber struct {
Email string `json:"email"`
Name string `json:"name"`
Status string `json:"status,omitempty"`
Lists []int `json:"lists"`
Attribs map[string]interface{} `json:"attribs,omitempty"`
PreconfirmSubscriptions bool `json:"preconfirm_subscriptions,omitempty"`
}
func init() {
flag.Var(&ListmonkURL, "newsletter-server-url", "Base URL of the listmonk newsletter server")
flag.IntVar(&ListmonkId, "newsletter-id", 1, "Listmonk identifier of the list receiving the new user")
}
func SubscribeToNewsletter(u *happydns.User) (err error) {
if ListmonkURL.URL == nil {
if ListmonkId != 0 {
log.Println("SubscribeToNewsletter: not subscribing user as newsletter server is not defined.")
}
return nil
}
url := ListmonkURL.URL
url.Path = filepath.Join(url.Path, "api/subscribers")
jsonForm := &ListmonkSubscriber{
Email: u.Email,
Name: genUsername(u.Email),
Status: "enabled",
Lists: []int{ListmonkId},
PreconfirmSubscriptions: true,
}
j, err := json.Marshal(jsonForm)
if err != nil {
log.Printf("SubscribeToNewsletter: unable to encode the first request body: %s", err.Error())
return fmt.Errorf("an error occured when trying to subscribe to the newsletter. Please try again later.")
}
req, err := http.NewRequest("POST", url.String(), bytes.NewReader(j))
if err != nil {
log.Printf("SubscribeToNewsletter: unable to create the first request: %s", err.Error())
return fmt.Errorf("an error occured when trying to subscribe to the newsletter. Please try again later.")
}
req.Header.Set("Content-Type", "application/json")
resp, err := http.DefaultClient.Do(req)
if err != nil {
log.Printf("SubscribeToNewsletter: unable to perform the first request body: %s", err.Error())
return fmt.Errorf("an error occured when trying to subscribe to the newsletter. Please try again later.")
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
var msg map[string]string
dec := json.NewDecoder(resp.Body)
dec.Decode(&msg)
log.Printf("SubscribeToNewsletter: unable to perform the first request body: %s", msg["message"])
return fmt.Errorf("an error occured when trying to subscribe to the newsletter. Please try again later.")
}
return
}

View File

@ -41,11 +41,11 @@ import (
"git.happydns.org/happyDomain/utils"
)
func genUsername(user *happydns.UserAuth) (toName string) {
if n := strings.Index(user.Email, "+"); n > 0 {
toName = user.Email[0:n]
func genUsername(email string) (toName string) {
if n := strings.Index(email, "+"); n > 0 {
toName = email[0:n]
} else {
toName = user.Email[0:strings.Index(user.Email, "@")]
toName = email[0:strings.Index(email, "@")]
}
if len(toName) > 1 {
toNameCopy := strings.Replace(toName, ".", " ", -1)
@ -68,7 +68,7 @@ func genUsername(user *happydns.UserAuth) (toName string) {
}
func SendValidationLink(opts *config.Options, user *happydns.UserAuth) error {
toName := genUsername(user)
toName := genUsername(user.Email)
return utils.SendMail(
&mail.Address{Name: toName, Address: user.Email},
"Your new account on happyDomain",
@ -87,7 +87,7 @@ In order to validate your account, please follow this link now:
}
func SendRecoveryLink(opts *config.Options, user *happydns.UserAuth) error {
toName := genUsername(user)
toName := genUsername(user.Email)
return utils.SendMail(
&mail.Address{Name: toName, Address: user.Email},
"Recover your happyDomain account",

View File

@ -41,6 +41,7 @@ import (
"github.com/gin-gonic/gin"
"github.com/golang-jwt/jwt/v5"
"git.happydns.org/happyDomain/actions"
"git.happydns.org/happyDomain/config"
"git.happydns.org/happyDomain/model"
"git.happydns.org/happyDomain/storage"
@ -51,6 +52,7 @@ type UserProfile struct {
Email string `json:"email"`
EmailVerified bool `json:"email_verified"`
CreatedAt time.Time `json:"created_at"`
Newsletter bool `json:"wantReceiveUpdate,omitempty"`
}
type UserClaims struct {
@ -84,6 +86,14 @@ func retrieveUserFromClaims(claims *UserClaims) (user *happydns.User, err error)
err = fmt.Errorf("has a correct JWT, but an error occured when trying to create the user: %w", err)
return
}
if claims.Profile.Newsletter {
err = actions.SubscribeToNewsletter(user)
if err != nil {
err = fmt.Errorf("something goes wrong during newsletter subscription: %w", err)
return
}
}
} else if time.Since(user.LastSeen) > time.Hour*12 {
// Update user's data when connected more than 12 hours
updateUserFromClaims(user, claims)

View File

@ -214,6 +214,7 @@ func checkAuth(opts *config.Options, c *gin.Context) {
Email: user.Email,
EmailVerified: user.EmailVerification != nil,
CreatedAt: user.CreatedAt,
Newsletter: user.AllowCommercials,
})
if err != nil {
log.Printf("%s %s", c.ClientIP(), err.Error())