feat: remove authentication requirement for avatar and image upload endpoints;

fix: remove 500 error responses from upload endpoints;
fix: return validation error strings instead of error lists;
fix: handle invalid avatar upload IDs with 400 Bad Request response;
fix: add missing S3Controller to controller initialization;
fix: change avatar_upload_id to string type and update validation rules;
chore: add license header to smtp.go;
refactor: replace manual proxy implementation with httputil.ReverseProxy;
fix: inject S3Service dependency into ProfileService;
fix: set color and color_grad fields during profile update;
fix: correct DTO mapping for profile and settings;
fix: check object existence before copying in SaveUpload;
fix: adjust profile DTO mapping function for proper pointer handling
This commit is contained in:
2025-08-02 03:47:56 +03:00
parent 669349e020
commit 5ed75c350a
14 changed files with 120 additions and 119 deletions

View File

@@ -28,7 +28,6 @@ import (
"path/filepath"
"github.com/gin-gonic/gin"
"github.com/go-playground/validator/v10"
"github.com/google/uuid"
"go.uber.org/zap"
)
@@ -127,10 +126,9 @@ func GetRequest[ModelT any](c *gin.Context) (*dto.Request[ModelT], error) {
validate := validation.NewValidator()
if err := validate.Struct(body); err != nil {
errorList := err.(validator.ValidationErrors)
c.AbortWithStatusJSON(
http.StatusBadRequest,
gin.H{"error": errorList})
gin.H{"error": err.Error()})
return nil, err
}

View File

@@ -81,7 +81,6 @@ func NewProfileController(_log *zap.Logger, _ps services.ProfileService) Control
}
}
// XXX: untested
// @Summary Get your profile
// @Tags Profile
// @Accept json
@@ -100,7 +99,6 @@ func (ctrl *ProfileController) getMyProfile(c *gin.Context) {
c.JSON(http.StatusOK, response)
}
// XXX: untested
// @Summary Get profile by username
// @Tags Profile
// @Accept json
@@ -131,12 +129,8 @@ func (ctrl *ProfileController) getProfileByUsername(c *gin.Context) {
}
c.JSON(http.StatusOK, response)
print(cinfo.Username)
panic("Not implemented")
}
// XXX: untested
// @Summary Get your profile settings
// @Tags Profile
// @Accept json
@@ -155,7 +149,6 @@ func (ctrl *ProfileController) getProfileSettings(c *gin.Context) {
c.JSON(http.StatusOK, response)
}
// XXX: untested
// @Summary Update your profile
// @Tags Profile
// @Accept json
@@ -169,7 +162,12 @@ func (ctrl *ProfileController) updateProfile(c *gin.Context) {
return
}
response, err := ctrl.ps.UpdateProfile(request.User, request.Body); if err != nil || !response {
response, err := ctrl.ps.UpdateProfile(request.User, request.Body); if err != nil {
if errors.Is(err, errs.ErrFileNotFound) {
c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid upload ID. Make sure file was uploaded and is not expired."})
}
c.Status(http.StatusInternalServerError)
return
}
@@ -177,7 +175,6 @@ func (ctrl *ProfileController) updateProfile(c *gin.Context) {
c.JSON(http.StatusOK, response)
}
// XXX: untested
// @Summary Update your profile's settings
// @Tags Profile
// @Accept json

View File

@@ -47,14 +47,14 @@ func NewS3Controller(_log *zap.Logger, _us services.S3Service) Controller {
{
HttpMethod: GET,
Path: "/avatar",
Authorization: enums.UserRole,
Authorization: enums.GuestRole,
Middleware: []gin.HandlerFunc{},
Function: ctrl.getAvatarUploadUrl,
},
{
HttpMethod: GET,
Path: "/image",
Authorization: enums.UserRole,
Authorization: enums.GuestRole,
Middleware: []gin.HandlerFunc{},
Function: ctrl.getImageUploadUrl,
},
@@ -62,14 +62,11 @@ func NewS3Controller(_log *zap.Logger, _us services.S3Service) Controller {
}
}
// XXX: untested
// @Summary Get presigned URL for avatar upload
// @Tags Upload
// @Accept json
// @Produce json
// @Security JWT
// @Success 200 {object} models.PresignedUploadResponse "Presigned URL and form data"
// @Failure 500 "Internal server error"
// @Router /upload/avatar [get]
func (ctrl *S3Controller) getAvatarUploadUrl(c *gin.Context) {
url, formData, err := ctrl.s3.CreateAvatarUrl()
@@ -85,14 +82,11 @@ func (ctrl *S3Controller) getAvatarUploadUrl(c *gin.Context) {
})
}
// XXX: untested
// @Summary Get presigned URL for image upload
// @Tags Upload
// @Accept json
// @Produce json
// @Security JWT
// @Success 200 {object} models.PresignedUploadResponse "Presigned URL and form data"
// @Failure 500 "Internal server error"
// @Router /upload/image [get]
func (ctrl *S3Controller) getImageUploadUrl(c *gin.Context) {
url, formData, err := ctrl.s3.CreateImageUrl()

View File

@@ -68,6 +68,7 @@ var Module = fx.Module("controllers",
fx.Annotate(NewServiceController, fx.ResultTags(`group:"controllers"`)),
fx.Annotate(NewAuthController, fx.ResultTags(`group:"controllers"`)),
fx.Annotate(NewProfileController, fx.ResultTags(`group:"controllers"`)),
fx.Annotate(NewS3Controller, fx.ResultTags(`group:"controllers"`)),
),
fx.Invoke(setupControllers),
)