package handler import ( "encoding/json" "net/http" "time" "github.com/golang-jwt/jwt/v5" db "github.com/multica-ai/multica/server/pkg/db/generated" ) var jwtSecret = []byte("multica-dev-secret-change-in-production") type UserResponse struct { ID string `json:"id"` Name string `json:"name"` Email string `json:"email"` AvatarURL *string `json:"avatar_url"` CreatedAt string `json:"created_at"` UpdatedAt string `json:"updated_at"` } func userToResponse(u db.User) UserResponse { return UserResponse{ ID: uuidToString(u.ID), Name: u.Name, Email: u.Email, AvatarURL: textToPtr(u.AvatarUrl), CreatedAt: timestampToString(u.CreatedAt), UpdatedAt: timestampToString(u.UpdatedAt), } } type LoginRequest struct { Email string `json:"email"` Name string `json:"name"` } type LoginResponse struct { Token string `json:"token"` User UserResponse `json:"user"` } func (h *Handler) Login(w http.ResponseWriter, r *http.Request) { var req LoginRequest if err := json.NewDecoder(r.Body).Decode(&req); err != nil { writeError(w, http.StatusBadRequest, "invalid request body") return } if req.Email == "" { writeError(w, http.StatusBadRequest, "email is required") return } // Try to find existing user user, err := h.Queries.GetUserByEmail(r.Context(), req.Email) if err != nil { // Create new user name := req.Name if name == "" { name = req.Email } user, err = h.Queries.CreateUser(r.Context(), db.CreateUserParams{ Name: name, Email: req.Email, }) if err != nil { writeError(w, http.StatusInternalServerError, "failed to create user: "+err.Error()) return } } // Generate JWT token := jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.MapClaims{ "sub": uuidToString(user.ID), "email": user.Email, "name": user.Name, "exp": time.Now().Add(72 * time.Hour).Unix(), "iat": time.Now().Unix(), }) tokenString, err := token.SignedString(jwtSecret) if err != nil { writeError(w, http.StatusInternalServerError, "failed to generate token") return } writeJSON(w, http.StatusOK, LoginResponse{ Token: tokenString, User: userToResponse(user), }) } func (h *Handler) GetMe(w http.ResponseWriter, r *http.Request) { userID := r.Header.Get("X-User-ID") if userID == "" { writeError(w, http.StatusUnauthorized, "user not authenticated") return } user, err := h.Queries.GetUser(r.Context(), parseUUID(userID)) if err != nil { writeError(w, http.StatusNotFound, "user not found") return } writeJSON(w, http.StatusOK, userToResponse(user)) }