fix port and email issues
This commit is contained in:
@@ -39,6 +39,6 @@ COPY --from=builder /app/static ./static
|
|||||||
# Copy .env (optional - can be overridden at runtime)
|
# Copy .env (optional - can be overridden at runtime)
|
||||||
COPY .env .env
|
COPY .env .env
|
||||||
|
|
||||||
EXPOSE 8080
|
EXPOSE 5000
|
||||||
|
|
||||||
CMD ["./server"]
|
CMD ["./server"]
|
||||||
1
go.mod
1
go.mod
@@ -5,7 +5,6 @@ go 1.25.4
|
|||||||
require (
|
require (
|
||||||
github.com/jackc/pgx/v5 v5.7.6
|
github.com/jackc/pgx/v5 v5.7.6
|
||||||
github.com/joho/godotenv v1.5.1
|
github.com/joho/godotenv v1.5.1
|
||||||
github.com/wneessen/go-mail v0.7.2
|
|
||||||
)
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
|
|||||||
2
go.sum
2
go.sum
@@ -18,8 +18,6 @@ github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UV
|
|||||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||||
github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk=
|
github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk=
|
||||||
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||||
github.com/wneessen/go-mail v0.7.2 h1:xxPnhZ6IZLSgxShebmZ6DPKh1b6OJcoHfzy7UjOkzS8=
|
|
||||||
github.com/wneessen/go-mail v0.7.2/go.mod h1:+TkW6QP3EVkgTEqHtVmnAE/1MRhmzb8Y9/W3pweuS+k=
|
|
||||||
golang.org/x/crypto v0.37.0 h1:kJNSjF/Xp7kU0iB2Z+9viTPMW4EqqsrywMXLJOOsXSE=
|
golang.org/x/crypto v0.37.0 h1:kJNSjF/Xp7kU0iB2Z+9viTPMW4EqqsrywMXLJOOsXSE=
|
||||||
golang.org/x/crypto v0.37.0/go.mod h1:vg+k43peMZ0pUMhYmVAWysMK35e6ioLh3wB8ZCAfbVc=
|
golang.org/x/crypto v0.37.0/go.mod h1:vg+k43peMZ0pUMhYmVAWysMK35e6ioLh3wB8ZCAfbVc=
|
||||||
golang.org/x/sync v0.17.0 h1:l60nONMj9l5drqw6jlhIELNv9I0A4OFgRsG9k2oT9Ug=
|
golang.org/x/sync v0.17.0 h1:l60nONMj9l5drqw6jlhIELNv9I0A4OFgRsG9k2oT9Ug=
|
||||||
|
|||||||
@@ -26,14 +26,14 @@ func LoadConfig() (*Config, error) {
|
|||||||
|
|
||||||
cfg := &Config{
|
cfg := &Config{
|
||||||
Host: getEnv("HOST", "0.0.0.0"),
|
Host: getEnv("HOST", "0.0.0.0"),
|
||||||
Port: getEnv("PORT", "8080"),
|
Port: getEnv("PORT", "5000"),
|
||||||
DBHost: getEnv("PG_HOST", "localhost"),
|
DBHost: getEnv("PG_HOST", ""),
|
||||||
DBPort: getEnv("PG_PORT", "5432"),
|
DBPort: getEnv("PG_PORT", ""),
|
||||||
DBName: getEnv("PG_DATABASE", "newsletter"),
|
DBName: getEnv("PG_DATABASE", ""),
|
||||||
DBUser: getEnv("PG_USER", "postgres"),
|
DBUser: getEnv("PG_USER", ""),
|
||||||
DBPass: getEnv("PG_PASSWORD", ""),
|
DBPass: getEnv("PG_PASSWORD", ""),
|
||||||
SMTPHost: getEnv("SMTP_SERVER", ""),
|
SMTPHost: getEnv("SMTP_SERVER", ""),
|
||||||
SMTPPort: getEnv("SMTP_PORT", "587"),
|
SMTPPort: getEnv("SMTP_PORT", ""),
|
||||||
SMTPUser: getEnv("SMTP_USER", ""),
|
SMTPUser: getEnv("SMTP_USER", ""),
|
||||||
SMTPPass: getEnv("SMTP_PASSWORD", ""),
|
SMTPPass: getEnv("SMTP_PASSWORD", ""),
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,13 @@
|
|||||||
package email
|
package email
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"crypto/tls"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"net"
|
||||||
|
"net/smtp"
|
||||||
|
"strconv"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/wneessen/go-mail"
|
|
||||||
"landing/internal/config"
|
"landing/internal/config"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -19,42 +23,111 @@ func (s *Sender) SendConfirmationEmail(
|
|||||||
email string,
|
email string,
|
||||||
unsubscribeLink string,
|
unsubscribeLink string,
|
||||||
) error {
|
) error {
|
||||||
client, err := mail.NewClient(
|
// Parse SMTP port from env
|
||||||
s.cfg.SMTPHost,
|
port, err := strconv.Atoi(s.cfg.SMTPPort)
|
||||||
mail.WithPort(587),
|
|
||||||
mail.WithSMTPAuth(mail.SMTPAuthPlain),
|
|
||||||
mail.WithUsername(s.cfg.SMTPUser),
|
|
||||||
mail.WithPassword(s.cfg.SMTPPass),
|
|
||||||
)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to create mail client: %w", err)
|
return fmt.Errorf("invalid SMTP port '%s': %w", s.cfg.SMTPPort, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
msg := mail.NewMsg()
|
// Build email message
|
||||||
if err := msg.From(s.cfg.SMTPUser); err != nil {
|
subject := "Thanks for subscribing!"
|
||||||
return fmt.Errorf("failed to set from: %w", err)
|
|
||||||
}
|
|
||||||
if err := msg.To(email); err != nil {
|
|
||||||
return fmt.Errorf("failed to set to: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
msg.Subject("Thanks for subscribing!")
|
|
||||||
|
|
||||||
htmlBody := fmt.Sprintf(`
|
htmlBody := fmt.Sprintf(`
|
||||||
<html>
|
<html>
|
||||||
<body>
|
<body>
|
||||||
<h1>Welcome!</h1>
|
<h1>Welcome to RideAware!</h1>
|
||||||
<p>Thank you for subscribing to our newsletter.</p>
|
<p>Thank you for subscribing to our newsletter.</p>
|
||||||
<p><a href="%s">Unsubscribe</a></p>
|
<p><a href="%s">Unsubscribe</a></p>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
`, unsubscribeLink)
|
`, unsubscribeLink)
|
||||||
|
|
||||||
msg.SetBodyString(mail.TypeTextHTML, htmlBody)
|
message := fmt.Sprintf(
|
||||||
|
"From: %s\r\nTo: %s\r\nSubject: %s\r\nContent-Type: text/html; charset=utf-8\r\n\r\n%s",
|
||||||
|
s.cfg.SMTPUser,
|
||||||
|
email,
|
||||||
|
subject,
|
||||||
|
htmlBody,
|
||||||
|
)
|
||||||
|
|
||||||
if err := client.DialAndSend(msg); err != nil {
|
// Create TLS config
|
||||||
return fmt.Errorf("failed to send email: %w", err)
|
tlsConfig := &tls.Config{
|
||||||
|
ServerName: s.cfg.SMTPHost,
|
||||||
|
}
|
||||||
|
|
||||||
|
// Send email using smtp.SendMail
|
||||||
|
addr := fmt.Sprintf("%s:%d", s.cfg.SMTPHost, port)
|
||||||
|
auth := smtp.PlainAuth("", s.cfg.SMTPUser, s.cfg.SMTPPass, s.cfg.SMTPHost)
|
||||||
|
|
||||||
|
// Use a custom dialer with timeout
|
||||||
|
conn, err := net.DialTimeout("tcp", addr, 10*time.Second)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to connect to SMTP server: %w", err)
|
||||||
|
}
|
||||||
|
defer conn.Close()
|
||||||
|
|
||||||
|
client, err := smtp.NewClient(conn, s.cfg.SMTPHost)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to create SMTP client: %w", err)
|
||||||
|
}
|
||||||
|
defer client.Close()
|
||||||
|
|
||||||
|
// Start TLS
|
||||||
|
if err := client.StartTLS(tlsConfig); err != nil {
|
||||||
|
return fmt.Errorf("failed to start TLS: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Authenticate
|
||||||
|
if err := client.Auth(auth); err != nil {
|
||||||
|
return fmt.Errorf("failed to authenticate: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set recipient and send
|
||||||
|
if err := client.Mail(s.cfg.SMTPUser); err != nil {
|
||||||
|
return fmt.Errorf("failed to set mail from: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := client.Rcpt(email); err != nil {
|
||||||
|
return fmt.Errorf("failed to set mail to: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
wc, err := client.Data()
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to get data writer: %w", err)
|
||||||
|
}
|
||||||
|
defer wc.Close()
|
||||||
|
|
||||||
|
if _, err := wc.Write([]byte(message)); err != nil {
|
||||||
|
return fmt.Errorf("failed to write message: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := client.Quit(); err != nil {
|
||||||
|
return fmt.Errorf("failed to quit SMTP: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// TestConnection tests SMTP connection without sending email
|
||||||
|
func (s *Sender) TestConnection() error {
|
||||||
|
port, err := strconv.Atoi(s.cfg.SMTPPort)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("invalid SMTP port '%s': %w", s.cfg.SMTPPort, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test TCP connection
|
||||||
|
addr := fmt.Sprintf("%s:%d", s.cfg.SMTPHost, port)
|
||||||
|
conn, err := net.DialTimeout("tcp", addr, 10*time.Second)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("TCP connection failed to %s: %w", addr, err)
|
||||||
|
}
|
||||||
|
defer conn.Close()
|
||||||
|
|
||||||
|
// Test SMTP connection
|
||||||
|
client, err := smtp.NewClient(conn, s.cfg.SMTPHost)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to create SMTP client: %w", err)
|
||||||
|
}
|
||||||
|
defer client.Close()
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user