127 lines
2.9 KiB
Go
127 lines
2.9 KiB
Go
package api
|
|
|
|
import (
|
|
"bytes"
|
|
"encoding/json"
|
|
"log/slog"
|
|
"net/http"
|
|
"net/url"
|
|
"os"
|
|
"strings"
|
|
"time"
|
|
|
|
"github.com/gin-gonic/gin"
|
|
)
|
|
|
|
const defaultAccountServiceURL = "http://localhost:8080"
|
|
|
|
var accountServiceHTTPClient = &http.Client{Timeout: 10 * time.Second}
|
|
|
|
func registerAuthRoutes(r *gin.RouterGroup) {
|
|
r.POST("/auth/register", handleAuthRegister)
|
|
}
|
|
|
|
func handleAuthRegister(c *gin.Context) {
|
|
name := strings.TrimSpace(c.PostForm("name"))
|
|
email := strings.ToLower(strings.TrimSpace(c.PostForm("email")))
|
|
password := c.PostForm("password")
|
|
confirm := c.PostForm("confirmPassword")
|
|
|
|
if email == "" || password == "" {
|
|
redirectWithError(c, "missing_fields")
|
|
return
|
|
}
|
|
|
|
if password != confirm {
|
|
redirectWithError(c, "password_mismatch")
|
|
return
|
|
}
|
|
|
|
payload := map[string]string{
|
|
"name": name,
|
|
"email": email,
|
|
"password": password,
|
|
}
|
|
|
|
body, err := json.Marshal(payload)
|
|
if err != nil {
|
|
slog.Error("marshal register payload", "err", err)
|
|
redirectWithError(c, "registration_failed")
|
|
return
|
|
}
|
|
|
|
req, err := http.NewRequestWithContext(
|
|
c.Request.Context(),
|
|
http.MethodPost,
|
|
accountServiceRegisterURL(),
|
|
bytes.NewReader(body),
|
|
)
|
|
if err != nil {
|
|
slog.Error("create account service request", "err", err)
|
|
redirectWithError(c, "registration_failed")
|
|
return
|
|
}
|
|
req.Header.Set("Content-Type", "application/json")
|
|
|
|
resp, err := accountServiceHTTPClient.Do(req)
|
|
if err != nil {
|
|
slog.Error("call account service", "err", err)
|
|
redirectWithError(c, "registration_failed")
|
|
return
|
|
}
|
|
defer resp.Body.Close()
|
|
|
|
if resp.StatusCode < 200 || resp.StatusCode >= 300 {
|
|
var result struct {
|
|
Error string `json:"error"`
|
|
}
|
|
if err := json.NewDecoder(resp.Body).Decode(&result); err != nil {
|
|
slog.Error("decode account service error", "err", err)
|
|
}
|
|
message := strings.TrimSpace(result.Error)
|
|
if message == "" {
|
|
message = "registration_failed"
|
|
}
|
|
redirectWithError(c, message)
|
|
return
|
|
}
|
|
|
|
redirectToLogin(c)
|
|
}
|
|
|
|
func redirectWithError(c *gin.Context, message string) {
|
|
target := &url.URL{Path: "/register"}
|
|
values := url.Values{}
|
|
values.Set("error", message)
|
|
target.RawQuery = values.Encode()
|
|
c.Redirect(http.StatusSeeOther, target.String())
|
|
}
|
|
|
|
func redirectToLogin(c *gin.Context) {
|
|
target := &url.URL{Path: "/login"}
|
|
values := url.Values{}
|
|
values.Set("registered", "1")
|
|
target.RawQuery = values.Encode()
|
|
c.Redirect(http.StatusSeeOther, target.String())
|
|
}
|
|
|
|
func accountServiceRegisterURL() string {
|
|
base := strings.TrimSuffix(resolveAccountServiceBaseURL(), "/")
|
|
return base + "/v1/register"
|
|
}
|
|
|
|
func resolveAccountServiceBaseURL() string {
|
|
candidates := []string{
|
|
os.Getenv("ACCOUNT_SERVICE_URL"),
|
|
os.Getenv("ACCOUNT_SERVICE_BASE_URL"),
|
|
os.Getenv("NEXT_PUBLIC_ACCOUNT_SERVICE_URL"),
|
|
}
|
|
for _, candidate := range candidates {
|
|
candidate = strings.TrimSpace(candidate)
|
|
if candidate != "" {
|
|
return candidate
|
|
}
|
|
}
|
|
return defaultAccountServiceURL
|
|
}
|