92 lines
2.2 KiB
Go
92 lines
2.2 KiB
Go
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})
|
|
}
|