package auth import ( "errors" "net/http" "github.com/gin-gonic/gin" "go.uber.org/zap" "git.kanopo.dev/rhythm/rhythm-backend/internal/config" "git.kanopo.dev/rhythm/rhythm-backend/internal/service/users" ) type Handler struct { svc users.Service log *zap.SugaredLogger cfg *config.Config } func NewHandler(svc users.Service, log *zap.SugaredLogger, cfg *config.Config) *Handler { return &Handler{ svc: svc, log: log, cfg: cfg, } } func (h *Handler) RegisterRoutes(rg *gin.RouterGroup) { rg.POST("/login", h.Login) rg.POST("/register", h.Register) } func setRefreshTokenCookie(c *gin.Context, token string, maxAge int) { c.SetCookie( "refresh_token", token, maxAge, "/", "", false, true, ) } func (h *Handler) Register(c *gin.Context) { var req struct { Email string `json:"email" binding:"required,email"` Password string `json:"password" binding:"required,min=8"` } if err := c.ShouldBindJSON(&req); err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) return } result, err := h.svc.Register(c.Request.Context(), req.Email, req.Password) if err != nil { h.log.Error("registration error", "error", err) c.JSON(http.StatusInternalServerError, gin.H{"error": "internal server error"}) return } setRefreshTokenCookie(c, result.RefreshToken, int(h.cfg.RefreshExpiry)) c.JSON(http.StatusCreated, gin.H{"accessToken": result.AccessToken}) } func (h *Handler) Login(c *gin.Context) { var req struct { Email string `json:"email" binding:"required,email"` Password string `json:"password" binding:"required"` } if err := c.ShouldBindJSON(&req); err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) return } result, err := h.svc.Login(c.Request.Context(), req.Email, req.Password) if err != nil { if errors.Is(err, users.ErrInvalidCredentials) { c.JSON(http.StatusUnauthorized, gin.H{"error": "invalid credentials"}) return } h.log.Error("login error", "error", err) c.JSON(http.StatusInternalServerError, gin.H{"error": "internal server error"}) return } setRefreshTokenCookie(c, result.RefreshToken, int(h.cfg.RefreshExpiry)) c.JSON(http.StatusOK, gin.H{"accessToken": result.AccessToken}) }