diff --git a/go-backend/internal/handlers/auth_handler.go b/go-backend/internal/handlers/auth_handler.go index 95addc5..54b4bbe 100644 --- a/go-backend/internal/handlers/auth_handler.go +++ b/go-backend/internal/handlers/auth_handler.go @@ -395,7 +395,7 @@ func generateRandomString(n int) (string, error) { if err != nil { return "", err } - return base64.URLEncoding.EncodeToString(b), nil + return base64.RawURLEncoding.EncodeToString(b), nil } func (h *AuthHandler) ForgotPassword(c *gin.Context) { diff --git a/go-backend/internal/services/email_service.go b/go-backend/internal/services/email_service.go index 5c5d5e9..12d0db2 100644 --- a/go-backend/internal/services/email_service.go +++ b/go-backend/internal/services/email_service.go @@ -6,6 +6,7 @@ import ( "fmt" "io" "net/http" + "net/url" "strings" "sync" "time" @@ -52,39 +53,40 @@ type sendPulseIdentity struct { func (s *EmailService) SendVerificationEmail(toEmail, toName, token string) error { subject := "Verify your Sojorn account" - // Ensure we don't double up on /api/v1 if it's already in the config apiBase := strings.TrimSuffix(s.config.APIBaseURL, "/api/v1") - verifyURL := fmt.Sprintf("%s/api/v1/auth/verify?token=%s", apiBase, token) + verifyURL := fmt.Sprintf("%s/api/v1/auth/verify?token=%s", apiBase, url.QueryEscape(token)) title := "Email Verification" - header := fmt.Sprintf("Hey %s! 👋", toName) + header := fmt.Sprintf("Hey %s!", toName) if toName == "" { - header = "Hey there! 👋" + header = "Hey there!" } content := ` -
Welcome to Sojorn — your vibrant new social space. We're thrilled to have you join our community!
+Welcome to Sojorn — your vibrant new social space. We're thrilled to have you join our community!
To get started in the app, please verify your email address by clicking the button below:
` footer := ` -If the button doesn't work, copy and paste this link into your browser:
- %s -|
+ If the button above doesn't work, copy and paste this link into your browser: + %s + |
This link expires in 1 hour. If you did not request this, you can safely ignore this email.
+|
+ If the button doesn't work, copy and paste this link: + %s + |
This link expires in 1 hour. If you did not request this, you can safely ignore this email.
` + footer = fmt.Sprintf(footer, resetURL, resetURL) htmlBody := s.buildHTMLEmail(title, header, content, resetURL, "Reset Password", footer) - textBody := fmt.Sprintf("Reset your Sojorn password: %s", resetURL) + textBody := fmt.Sprintf("Reset your Sojorn password by visiting this link:\n\n%s\n\nThis link expires in 1 hour.", resetURL) return s.sendEmail(toEmail, toName, subject, htmlBody, textBody) } @@ -257,49 +266,64 @@ func (s *EmailService) AddSubscriber(email, name string) { } func (s *EmailService) buildHTMLEmail(title, header, content, buttonURL, buttonText, footer string) string { - return fmt.Sprintf(` - - + return fmt.Sprintf(` + + +