diff --git a/internal/auth/routes.go b/internal/auth/routes.go index 510601a..d101ca7 100644 --- a/internal/auth/routes.go +++ b/internal/auth/routes.go @@ -1,8 +1,18 @@ package auth import ( + "encoding/json" + "fmt" + "net/http" + "time" + "gitea.local/admin/hspguard/internal/repository" + "gitea.local/admin/hspguard/internal/types" + "gitea.local/admin/hspguard/internal/util" + "gitea.local/admin/hspguard/internal/web" "github.com/go-chi/chi/v5" + "github.com/golang-jwt/jwt/v5" + "github.com/google/uuid" ) type AuthHandler struct { @@ -16,6 +26,87 @@ func NewAuthHandler(repo *repository.Queries) *AuthHandler { } func (h *AuthHandler) RegisterRoutes(router chi.Router, api chi.Router) { - + api.Get("/profile", h.getProfile) + api.Post("/login", h.login) +} + +func (h *AuthHandler) getProfile(w http.ResponseWriter, r *http.Request) { + userId, ok := util.GetRequestUserId(r.Context()) + if !ok { + web.Error(w, "failed to get user id from auth session", http.StatusInternalServerError) + return + } + + user, err := h.repo.FindUserId(r.Context(), uuid.MustParse(userId)) + if err != nil { + web.Error(w, "user with provided id does not exist", http.StatusUnauthorized) + return + } + + if err := json.NewEncoder(w).Encode(map[string]any{ + "full_name": user.FullName, + "email": user.Email, + "phoneNumber": user.PhoneNumber, + "isAdmin": user.IsAdmin, + "last_login": user.LastLogin, + "updated_at": user.UpdatedAt, + "created_at": user.CreatedAt, + }); err != nil { + web.Error(w, "failed to encode user profile", http.StatusInternalServerError) + } +} + +type LoginParams struct { + Email string `json:"email"` + Password string `json:"password"` +} + +func (h *AuthHandler) login(w http.ResponseWriter, r *http.Request) { + var params LoginParams + + decoder := json.NewDecoder(r.Body) + if err := decoder.Decode(¶ms); err != nil { + web.Error(w, "failed to parse request body", http.StatusBadRequest) + return + } + + if params.Email == "" || params.Password == "" { + web.Error(w, "missing required fields", http.StatusBadRequest) + return + } + + user, err := h.repo.FindUserEmail(r.Context(), params.Email) + if err != nil { + web.Error(w, "user with provided email does not exists", http.StatusBadRequest) + return + } + + claims := types.UserClaims{ + UserID: user.ID.String(), + RegisteredClaims: jwt.RegisteredClaims{ + Issuer: "hspguard", + Subject: user.Email, + IssuedAt: jwt.NewNumericDate(time.Now()), + ExpiresAt: jwt.NewNumericDate(time.Now().Add(time.Hour)), + }, + } + + token, err := SignJwtToken(claims) + if err != nil { + web.Error(w, fmt.Sprintf("failed to generate access token: %v", err), http.StatusBadRequest) + return + } + + encoder := json.NewEncoder(w) + + type Response struct { + Token string `json:"token"` + } + + if err := encoder.Encode(Response{ + Token: token, + }); err != nil { + web.Error(w, "failed to encode response", http.StatusInternalServerError) + } }