Initial commit of Descrybe v2 without local scratch artifacts.
Drop one-shot tmp/axe scripts and agent i18n scratch so the Gitea tree is deployable.
This commit is contained in:
@@ -0,0 +1,98 @@
|
||||
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"})
|
||||
}
|
||||
Reference in New Issue
Block a user