package auth import ( "RenewCMS/api/pkg/apperr" "RenewCMS/api/pkg/claims" "RenewCMS/api/pkg/payload" "RenewCMS/api/pkg/publicuser" "RenewCMS/internal/domain/author" "RenewCMS/internal/domain/role" "RenewCMS/internal/domain/user" "RenewCMS/internal/infrastructure/useCases" "encoding/json" "errors" "net/http" ) type MeHandler struct { GetUseCase *useCases.GetUserUseCase GetAuthorUseCase *useCases.GetMyAuthorUseCase GetAccessUseCase *useCases.GetMyAccessUseCase } func NewMeHandler(getUser *useCases.GetUserUseCase, getAuthor *useCases.GetMyAuthorUseCase, getAccess *useCases.GetMyAccessUseCase) *MeHandler { return &MeHandler{ GetUseCase: getUser, GetAuthorUseCase: getAuthor, GetAccessUseCase: getAccess, } } type meAuthor struct { author.Byline ArticleCount int `json:"article_count"` } type meAccess struct { Role payload.RoleRef `json:"role"` Permissions []role.Grant `json:"permissions"` RoleAssignedBy *payload.RoleAssigner `json:"role_assigned_by"` } type meResponse struct { publicuser.PublicUser PendingEmail *string `json:"pending_email"` Author *meAuthor `json:"author"` Access meAccess `json:"access"` } func toMeAccess(access useCases.Access) meAccess { return meAccess{ Role: payload.RoleRefOf(useCases.NewRoleRef(access.Role)), Permissions: access.Permissions, RoleAssignedBy: payload.RoleAssignerPtrOf(access.RoleAssignedBy), } } func toMeAuthor(found *author.Author) *meAuthor { if found == nil { return nil } return &meAuthor{Byline: found.Byline(), ArticleCount: found.ArticleCount} } func pendingEmailOf(account user.User) *string { if account.PendingEmail == "" { return nil } return &account.PendingEmail } func (h *MeHandler) Me(w http.ResponseWriter, r *http.Request) { userId, ok := claims.UserId(r) if !ok { http.Error(w, apperr.UnauthorizedErrorMessage, http.StatusUnauthorized) return } loadedUser, err := h.GetUseCase.GetUser(userId) if err != nil { if errors.Is(err, user.ErrUserNotFound) { http.Error(w, apperr.UnauthorizedErrorMessage, http.StatusUnauthorized) return } http.Error(w, "Internal server error", http.StatusInternalServerError) return } linked, err := h.GetAuthorUseCase.Get(loadedUser.ID) if err != nil { http.Error(w, "Internal server error", http.StatusInternalServerError) return } access, err := h.GetAccessUseCase.Get(loadedUser) if err != nil { http.Error(w, "Internal server error", http.StatusInternalServerError) return } body, err := json.Marshal(meResponse{PublicUser: publicuser.New(loadedUser), PendingEmail: pendingEmailOf(loadedUser), Author: toMeAuthor(linked), Access: toMeAccess(access)}) if err != nil { http.Error(w, "Internal server error", http.StatusInternalServerError) return } w.Header().Set("Cache-Control", "no-store") _, _ = w.Write(body) }