feat(API): optional display name on users

This commit is contained in:
fsylvain committed 2026-09-29 06:52:58 +02:00
1 parent 792aba433d
commit 7aae704d0a
22 files changed
+1051 -40

No files matched your search

+2 -1
View File
@@ -3,6 +3,7 @@ package auth
import (
"RenewCMS/api/pkg/apperr"
"RenewCMS/api/pkg/claims"
"RenewCMS/api/pkg/publicuser"
"RenewCMS/internal/domain/user"
"RenewCMS/internal/infrastructure/useCases"
"encoding/json"
@@ -37,7 +38,7 @@ func (h *MeHandler) Me(w http.ResponseWriter, r *http.Request) {
return
}
body, err := json.Marshal(newPublicUser(loadedUser))
body, err := json.Marshal(publicuser.New(loadedUser))
if err != nil {
http.Error(w, "Internal server error", http.StatusInternalServerError)
return
+2 -22
View File
@@ -3,13 +3,13 @@ package auth
import (
"RenewCMS/api/pkg/apperr"
"RenewCMS/api/pkg/claims"
"RenewCMS/api/pkg/publicuser"
validator "RenewCMS/api/pkg/validator"
"RenewCMS/internal/domain/user"
"RenewCMS/internal/infrastructure/useCases"
"encoding/json"
"errors"
"net/http"
"time"
)
type VerificationHandler struct {
@@ -22,26 +22,6 @@ type VerifyCredentials struct {
Code string `json:"code" validate:"required"`
}
type PublicUser struct {
ID uint32 `json:"id"`
Username string `json:"username"`
Email string `json:"email"`
IsVerified bool `json:"is_verified"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
}
func newPublicUser(u user.User) PublicUser {
return PublicUser{
ID: u.ID,
Username: u.Username,
Email: u.Email,
IsVerified: u.IsVerified,
CreatedAt: u.CreatedAt,
UpdatedAt: u.UpdatedAt,
}
}
func NewVerificationHandler(verify *useCases.VerifyUserUseCase, cancel *useCases.CancelRegistrationUseCase, isProduction bool) *VerificationHandler {
return &VerificationHandler{
VerifyUseCase: verify,
@@ -84,7 +64,7 @@ func (h *VerificationHandler) Verify(w http.ResponseWriter, r *http.Request) {
return
}
body, err := json.Marshal(newPublicUser(verifiedUser))
body, err := json.Marshal(publicuser.New(verifiedUser))
if err != nil {
http.Error(w, "Internal server error", http.StatusInternalServerError)
return
+70
View File
@@ -0,0 +1,70 @@
package user
import (
"RenewCMS/api/pkg/apperr"
"RenewCMS/api/pkg/claims"
"RenewCMS/api/pkg/publicuser"
validator "RenewCMS/api/pkg/validator"
"RenewCMS/internal/domain/user"
"RenewCMS/internal/infrastructure/useCases"
"encoding/json"
"errors"
"net/http"
)
type Handler struct {
UpdateProfileUseCase *useCases.UpdateUserProfileUseCase
}
type UpdateProfileRequest struct {
DisplayName *string `json:"display_name" validate:"required"`
}
func NewHandler(updateProfile *useCases.UpdateUserProfileUseCase) *Handler {
return &Handler{
UpdateProfileUseCase: updateProfile,
}
}
func (h *Handler) UpdateMe(w http.ResponseWriter, r *http.Request) {
var request UpdateProfileRequest
err := json.NewDecoder(r.Body).Decode(&request)
if err != nil {
http.Error(w, apperr.BodyErrorMessage, http.StatusBadRequest)
return
}
err = validator.Validate.Struct(request)
if err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
userId, ok := claims.UserId(r)
if !ok {
http.Error(w, apperr.UnauthorizedErrorMessage, http.StatusUnauthorized)
return
}
updatedUser, err := h.UpdateProfileUseCase.UpdateDisplayName(userId, *request.DisplayName)
if err != nil {
if errors.Is(err, user.ErrInvalidDisplayName) {
http.Error(w, apperr.DisplayNameErrorMessage, http.StatusBadRequest)
return
}
if errors.Is(err, user.ErrUserNotFound) {
http.Error(w, apperr.UnauthorizedErrorMessage, http.StatusUnauthorized)
return
}
http.Error(w, "Internal server error", http.StatusInternalServerError)
return
}
body, err := json.Marshal(publicuser.New(updatedUser))
if err != nil {
http.Error(w, "Internal server error", http.StatusInternalServerError)
return
}
w.Header().Set("Cache-Control", "no-store")
_, _ = w.Write(body)
}