mirror of
https://github.com/Dvorinka/SEEN.git
synced 2026-06-04 12:33:02 +00:00
137 lines
3.5 KiB
Go
137 lines
3.5 KiB
Go
package handlers
|
|
|
|
import (
|
|
"errors"
|
|
"net/http"
|
|
|
|
"github.com/gin-gonic/gin"
|
|
"github.com/tdvorak/seen/backend/internal/services/auth"
|
|
"github.com/tdvorak/seen/backend/pkg/httpx"
|
|
)
|
|
|
|
type AuthHandler struct {
|
|
service *auth.Service
|
|
}
|
|
|
|
func NewAuthHandler(service *auth.Service) *AuthHandler {
|
|
return &AuthHandler{service: service}
|
|
}
|
|
|
|
type registerRequest struct {
|
|
Email string `json:"email"`
|
|
Password string `json:"password"`
|
|
DisplayName string `json:"displayName"`
|
|
}
|
|
|
|
type loginRequest struct {
|
|
Email string `json:"email"`
|
|
Password string `json:"password"`
|
|
}
|
|
|
|
type refreshRequest struct {
|
|
RefreshToken string `json:"refreshToken"`
|
|
}
|
|
|
|
func (h *AuthHandler) Me(c *gin.Context) {
|
|
accessToken, ok := bearerToken(c.GetHeader("Authorization"))
|
|
if !ok {
|
|
httpx.JSONError(c, http.StatusUnauthorized, "missing bearer token")
|
|
return
|
|
}
|
|
|
|
user, err := h.service.UserFromAccessToken(c.Request.Context(), accessToken)
|
|
if err != nil {
|
|
switch {
|
|
case errors.Is(err, auth.ErrInvalidToken):
|
|
httpx.JSONError(c, http.StatusUnauthorized, err.Error())
|
|
default:
|
|
httpx.JSONError(c, http.StatusInternalServerError, "failed to resolve user")
|
|
}
|
|
return
|
|
}
|
|
|
|
httpx.JSON(c, http.StatusOK, user)
|
|
}
|
|
|
|
func (h *AuthHandler) Register(c *gin.Context) {
|
|
var request registerRequest
|
|
if err := c.ShouldBindJSON(&request); err != nil {
|
|
httpx.JSONError(c, http.StatusBadRequest, "invalid request body")
|
|
return
|
|
}
|
|
|
|
result, err := h.service.Register(c.Request.Context(), auth.RegisterInput{
|
|
Email: request.Email,
|
|
Password: request.Password,
|
|
DisplayName: request.DisplayName,
|
|
})
|
|
if err != nil {
|
|
switch {
|
|
case errors.Is(err, auth.ErrInvalidInput):
|
|
httpx.JSONError(c, http.StatusBadRequest, err.Error())
|
|
case errors.Is(err, auth.ErrEmailTaken):
|
|
httpx.JSONError(c, http.StatusConflict, err.Error())
|
|
default:
|
|
httpx.JSONError(c, http.StatusInternalServerError, "register failed")
|
|
}
|
|
return
|
|
}
|
|
|
|
httpx.JSON(c, http.StatusCreated, result)
|
|
}
|
|
|
|
func (h *AuthHandler) Login(c *gin.Context) {
|
|
var request loginRequest
|
|
if err := c.ShouldBindJSON(&request); err != nil {
|
|
httpx.JSONError(c, http.StatusBadRequest, "invalid request body")
|
|
return
|
|
}
|
|
|
|
result, err := h.service.Login(c.Request.Context(), auth.LoginInput{
|
|
Email: request.Email,
|
|
Password: request.Password,
|
|
UserAgent: c.GetHeader("User-Agent"),
|
|
IP: c.ClientIP(),
|
|
})
|
|
if err != nil {
|
|
switch {
|
|
case errors.Is(err, auth.ErrInvalidInput):
|
|
httpx.JSONError(c, http.StatusBadRequest, err.Error())
|
|
case errors.Is(err, auth.ErrInvalidCredentials):
|
|
httpx.JSONError(c, http.StatusUnauthorized, err.Error())
|
|
default:
|
|
httpx.JSONError(c, http.StatusInternalServerError, "login failed")
|
|
}
|
|
return
|
|
}
|
|
|
|
httpx.JSON(c, http.StatusOK, result)
|
|
}
|
|
|
|
func (h *AuthHandler) Refresh(c *gin.Context) {
|
|
var request refreshRequest
|
|
if err := c.ShouldBindJSON(&request); err != nil {
|
|
httpx.JSONError(c, http.StatusBadRequest, "invalid request body")
|
|
return
|
|
}
|
|
|
|
result, err := h.service.Refresh(c.Request.Context(), auth.RefreshInput{
|
|
RefreshToken: request.RefreshToken,
|
|
UserAgent: c.GetHeader("User-Agent"),
|
|
IP: c.ClientIP(),
|
|
})
|
|
if err != nil {
|
|
switch {
|
|
case errors.Is(err, auth.ErrInvalidInput):
|
|
httpx.JSONError(c, http.StatusBadRequest, err.Error())
|
|
case errors.Is(err, auth.ErrInvalidSession):
|
|
httpx.JSONError(c, http.StatusUnauthorized, err.Error())
|
|
default:
|
|
httpx.JSONError(c, http.StatusInternalServerError, "refresh failed")
|
|
}
|
|
return
|
|
}
|
|
|
|
httpx.JSON(c, http.StatusOK, result)
|
|
}
|