package httpapi import ( "errors" "net/http" "github.com/descrybe/descrybe-v2/apps/api/internal/auth" "github.com/go-chi/chi/v5" "github.com/google/uuid" ) func (s *Server) handleCompleteSetPassword(w http.ResponseWriter, r *http.Request) { var body struct { Token string `json:"token"` Password string `json:"password"` } if err := DecodeJSON(r, &body); err != nil { Error(w, http.StatusBadRequest, "invalid json") return } uid, err := auth.ParseSetPasswordToken(s.Config.TokenSigningSecret, body.Token) if err != nil { Error(w, http.StatusBadRequest, "invalid or expired token") return } if sessionEmail, ok := s.sessionUserEmail(r.Context()); ok { user, gerr := s.Auth.GetUser(r.Context(), uid) if gerr != nil { Error(w, http.StatusBadRequest, "invalid or expired token") return } if !auth.EmailsEqual(sessionEmail, user.Email) { writeEmailMismatch(w, sessionEmail, user.Email) return } } if err := s.Auth.SetPassword(r.Context(), uid, body.Password); err != nil { if errors.Is(err, auth.ErrPasswordAlreadySet) { Error(w, http.StatusBadRequest, "password already set") return } ClientOrLog(w, http.StatusBadRequest, "could not set password", err, auth.ClientError) return } JSON(w, http.StatusOK, map[string]string{"status": "ok"}) } func (s *Server) handleUpdateProfile(w http.ResponseWriter, r *http.Request) { uid, ok := UserIDFromContext(r.Context()) if !ok { Error(w, http.StatusUnauthorized, "unauthorized") return } var body struct { Name string `json:"name"` } if err := DecodeJSON(r, &body); err != nil { Error(w, http.StatusBadRequest, "invalid json") return } user, err := s.Auth.UpdateProfile(r.Context(), uid, body.Name) if err != nil { ClientOrLog(w, http.StatusBadRequest, "could not update profile", err, auth.ClientError) return } JSON(w, http.StatusOK, user) } func (s *Server) handleListInvites(w http.ResponseWriter, r *http.Request) { if !s.allowCompanyAdminOrPlatform(w, r) { return } cid, _ := CompanyIDFromContext(r.Context()) limit, offset := ParseLimitOffset(r) page, total, err := s.Auth.ListPendingInvites(r.Context(), cid, limit, offset) if err != nil { Error(w, http.StatusInternalServerError, "list failed") return } JSON(w, http.StatusOK, map[string]any{"invites": page, "total": total, "limit": limit, "offset": offset}) } func (s *Server) handleRevokeInvite(w http.ResponseWriter, r *http.Request) { if !s.allowCompanyAdminOrPlatform(w, r) { return } cid, _ := CompanyIDFromContext(r.Context()) id, err := uuid.Parse(chi.URLParam(r, "inviteID")) if err != nil { Error(w, http.StatusBadRequest, "invalid id") return } if err := s.Auth.RevokeInvite(r.Context(), cid, id); err != nil { ClientOrLog(w, http.StatusBadRequest, "could not revoke invite", err, auth.ClientError) return } JSON(w, http.StatusOK, map[string]string{"status": "ok"}) }