add new user set avatar and profile background

This commit is contained in:
gitGnome
2026-04-28 11:16:37 +02:00
parent 6f7a913e64
commit 8697cd2632
10 changed files with 203 additions and 228 deletions
+139 -8
View File
@@ -2,6 +2,8 @@ package httpRequest
import (
json2 "encoding/json"
"go-socket/packages/postgresql"
"go-socket/packages/types"
"net/http"
"strings"
@@ -42,7 +44,7 @@ func HandleAttachmentFileUpload(response http.ResponseWriter, request *http.Requ
defer file.Close()
contentType := header.Header.Get("Content-Type")
key := minio.GetKey(minio.GetKeyOptions{
key := minio.GetKey(&minio.GetKeyOptions{
ConnectionId: conn.Id,
MimeType: contentType,
UploadType: minio.ConnectionFile,
@@ -60,6 +62,62 @@ func HandleAttachmentFileUpload(response http.ResponseWriter, request *http.Requ
response.Write([]byte(key))
}
func HandleSetUserAvatar(response http.ResponseWriter, request *http.Request) {
if !validCheckWithResponseOnFail(&response, request, avatar) {
return
}
ctx := request.Context()
user, err := getUserByToken(ctx, request.Header.Get("token"))
if err != nil {
http.Error(response, "invalid token", http.StatusUnauthorized)
return
}
file, header, err := request.FormFile("file")
if err != nil {
http.Error(response, "missing file", http.StatusBadRequest)
return
}
defer file.Close()
isImg, contentType, err := isImage(file)
if err != nil || !isImg {
http.Error(response, "invalid file", http.StatusBadRequest)
return
}
key := minio.GetKey(&minio.GetKeyOptions{
MimeType: contentType,
UploadType: minio.UserAvatar,
UserId: user.Id,
})
err = minio.Upload(ctx, key, file, header.Size, contentType, map[string]string{
"originalName": header.Filename,
"uploaderId": user.Id.String(),
})
if err != nil {
http.Error(response, "upload failed", http.StatusInternalServerError)
return
}
if user.AvatarUrl != "" {
if err = minio.Delete(ctx, user.AvatarUrl); err != nil {
minio.Delete(ctx, key)
http.Error(response, "internal server error", http.StatusInternalServerError)
return
}
}
user.AvatarUrl = key
err = postgresql.UserUpdateProfile(ctx, user, &types.UserProfileUpdateList{Avatar: true})
if err != nil {
http.Error(response, "failed to update user avatar", http.StatusInternalServerError)
minio.Delete(ctx, user.AvatarUrl)
return
}
response.WriteHeader(http.StatusCreated)
}
func HandleGetUserAvatar(response http.ResponseWriter, request *http.Request) {
if !validCheckWithResponseOnFail(&response, request, normal) {
return
@@ -85,18 +143,82 @@ func HandleGetUserAvatar(response http.ResponseWriter, request *http.Request) {
}
if target.AvatarUrl == "" {
http.Error(response, "no avatar", http.StatusNotFound)
http.Error(response, "user have no avatar", http.StatusNoContent)
return
}
url, _, err := minio.GetDownloadUrlAndMetadata(ctx, target.AvatarUrl)
url, meta, err := minio.GetDownloadUrlAndMetadata(ctx, target.AvatarUrl)
if err != nil {
http.Error(response, "internal server error", http.StatusInternalServerError)
return
}
json, err := json2.Marshal(map[string]any{
"url": url.String(),
"metadata": meta,
})
if err != nil {
http.Error(response, "json error", http.StatusInternalServerError)
}
response.WriteHeader(http.StatusOK)
response.Write([]byte(url.String()))
response.Write(json)
}
func HandleSetUserProfileBg(response http.ResponseWriter, request *http.Request) {
if !validCheckWithResponseOnFail(&response, request, profileBg) {
return
}
ctx := request.Context()
user, err := getUserByToken(ctx, request.Header.Get("token"))
if err != nil {
http.Error(response, "invalid token", http.StatusUnauthorized)
return
}
file, header, err := request.FormFile("file")
if err != nil {
http.Error(response, "missing file", http.StatusBadRequest)
return
}
defer file.Close()
isImg, contentType, err := isImage(file)
if err != nil || !isImg {
http.Error(response, "invalid file", http.StatusBadRequest)
return
}
key := minio.GetKey(&minio.GetKeyOptions{
MimeType: contentType,
UploadType: minio.UserProfileBg,
UserId: user.Id,
})
err = minio.Upload(ctx, key, file, header.Size, contentType, map[string]string{
"originalName": header.Filename,
"uploaderId": user.Id.String(),
})
if err != nil {
http.Error(response, "upload failed", http.StatusInternalServerError)
return
}
if user.ProfileBgUrl != "" {
if err = minio.Delete(ctx, user.ProfileBgUrl); err != nil {
minio.Delete(ctx, key)
http.Error(response, "internal server error", http.StatusInternalServerError)
return
}
}
user.ProfileBgUrl = key
err = postgresql.UserUpdateProfile(ctx, user, &types.UserProfileUpdateList{ProfileBg: true})
if err != nil {
http.Error(response, "failed to update user profile background", http.StatusInternalServerError)
minio.Delete(ctx, user.ProfileBgUrl)
return
}
response.WriteHeader(http.StatusCreated)
}
func HandleGetUserProfileBg(response http.ResponseWriter, request *http.Request) {
@@ -105,7 +227,8 @@ func HandleGetUserProfileBg(response http.ResponseWriter, request *http.Request)
}
ctx := request.Context()
if _, err := getUserByToken(ctx, request.Header.Get("token")); err != nil {
_, err := getUserByToken(ctx, request.Header.Get("token"))
if err != nil {
http.Error(response, "invalid token", http.StatusUnauthorized)
return
}
@@ -123,18 +246,26 @@ func HandleGetUserProfileBg(response http.ResponseWriter, request *http.Request)
}
if target.ProfileBgUrl == "" {
http.Error(response, "no profile background", http.StatusNotFound)
http.Error(response, "user have no profile background", http.StatusNoContent)
return
}
url, _, err := minio.GetDownloadUrlAndMetadata(ctx, target.ProfileBgUrl)
url, meta, err := minio.GetDownloadUrlAndMetadata(ctx, target.ProfileBgUrl)
if err != nil {
http.Error(response, "internal server error", http.StatusInternalServerError)
return
}
json, err := json2.Marshal(map[string]any{
"url": url.String(),
"metadata": meta,
})
if err != nil {
http.Error(response, "json error", http.StatusInternalServerError)
}
response.WriteHeader(http.StatusOK)
response.Write([]byte(url.String()))
response.Write(json)
}
func HandleAttachmentFileDownload(response http.ResponseWriter, request *http.Request) {
+19 -19
View File
@@ -90,22 +90,22 @@ func getHubUserIfValidWithResponseOnFail(ctx context.Context, response http.Resp
return user, hubUser, hub, nil
}
func getHubChannelIfValidWithResponseOnFail(ctx context.Context, response http.ResponseWriter, hub *types.Hub, hubUser *types.HubUser, channelId string) (
*types.HubChannel, error) {
channelUuid, err := convertions.StringToUuid(channelId)
if err != nil {
http.Error(response, "invalid channelid", http.StatusBadRequest)
return nil, errors.New("invalid channelid")
}
channel, ok := hub.Channels[channelUuid]
if !ok {
http.Error(response, "invalid channelid", http.StatusBadRequest)
return nil, errors.New("invalid channelid")
}
if !haveHubUserPermissionsOnChannel(types.CachedUserCanView, hubUser, channel) {
return nil, errors.New("invalid channelid")
}
return channel, nil
}
//func getHubChannelIfValidWithResponseOnFail(ctx context.Context, response http.ResponseWriter, hub *types.Hub, hubUser *types.HubUser, channelId string) (
// *types.HubChannel, error) {
// channelUuid, err := convertions.StringToUuid(channelId)
// if err != nil {
// http.Error(response, "invalid channelid", http.StatusBadRequest)
// return nil, errors.New("invalid channelid")
// }
// channel, ok := hub.Channels[channelUuid]
// if !ok {
// http.Error(response, "invalid channelid", http.StatusBadRequest)
// return nil, errors.New("invalid channelid")
// }
//
// if !haveHubUserPermissionsOnChannel(types.CachedUserCanView, hubUser, channel) {
// return nil, errors.New("invalid channelid")
// }
//
// return channel, nil
//}
-61
View File
@@ -4,10 +4,8 @@ import (
"net/http"
"time"
"go-socket/packages/Enums/WsEventType"
"go-socket/packages/cache"
"go-socket/packages/types"
"go-socket/packages/wsServer"
"github.com/google/uuid"
)
@@ -134,65 +132,6 @@ func HandleHubCreate(response http.ResponseWriter, request *http.Request) {
cache.SaveHub(hub)
}
func HandleChannelSendMessage(response http.ResponseWriter, request *http.Request) {
if !validCheckWithResponseOnFail(&response, request, normal) {
return
}
ctx := request.Context()
user, hubUser, hub, err := getHubUserIfValidWithResponseOnFail(ctx, response, request.Header.Get("token"), request.FormValue("hubid"))
if err != nil {
return
}
msgContent := request.FormValue("msgContent")
attachedFile := request.FormValue("attachedFile")
if msgContent == "" && attachedFile == "" {
http.Error(response, "empty msgContent", http.StatusBadRequest)
return
}
channel, err := getHubChannelIfValidWithResponseOnFail(ctx, response, hub, hubUser, request.FormValue("channelid"))
if err != nil {
return
}
if !haveHubUserPermissionsOnChannel(types.CachedUserCanMessage, hubUser, channel) {
http.Error(response, "cannot send messages here", http.StatusUnauthorized)
return
}
message := &types.Message{
Id: uuid.New(),
AttachedFile: "",
Content: msgContent,
Sender: user.Id,
Receiver: channel.Id,
CreatedAt: time.Now(),
}
channel.Mu.RLock()
recipients := make([]uuid.UUID, 0, len(channel.UsersCachedPermissions))
for id, userCachedPerms := range channel.UsersCachedPermissions {
if userCachedPerms.CanReadHistory() && id != user.Id {
recipients = append(recipients, id)
}
}
channel.Mu.RUnlock()
for _, id := range recipients {
targetUser, err := cache.GetUserById(id)
if err != nil {
// todo Add to postgres in future
continue
}
wsServer.WsSendMessageCloseIfTimeout(targetUser, types.WsEventMessage{
Type: WsEventType.HubMessage,
Event: message,
})
}
}
func HandleHubJoin(response http.ResponseWriter, request *http.Request) {
if !validCheckWithResponseOnFail(&response, request, normal) {
return
+2 -131
View File
@@ -5,11 +5,8 @@ import (
"net/http"
"time"
"go-socket/packages/config"
"go-socket/packages/convertions"
"go-socket/packages/minio"
"go-socket/packages/cache"
"go-socket/packages/convertions"
"go-socket/packages/passwords"
"go-socket/packages/postgresql"
"go-socket/packages/tokens"
@@ -152,7 +149,7 @@ func HandleUserModProfile(response http.ResponseWriter, request *http.Request) {
return
}
var updateList types.UserProfileUpdateList
updateList := &types.UserProfileUpdateList{}
if pronouns := request.FormValue("pronouns"); pronouns != "" {
if len(pronouns) > 32 {
@@ -190,132 +187,6 @@ func HandleUserModProfile(response http.ResponseWriter, request *http.Request) {
response.WriteHeader(http.StatusAccepted)
}
func HandleUserModAvatar(response http.ResponseWriter, request *http.Request) {
if !validCheckWithResponseOnFail(&response, request, avatar) {
return
}
ctx := request.Context()
user, err := getUserByToken(ctx, request.Header.Get("token"))
if err != nil {
http.Error(response, "invalid token", http.StatusUnauthorized)
return
}
request.Body = http.MaxBytesReader(response, request.Body, int64(config.MaxRequestWithAvatarBytes))
if err = request.ParseMultipartForm(int64(config.MaxRequestBytes)); err != nil {
http.Error(response, "invalid multipart form", http.StatusBadRequest)
return
}
file, header, err := request.FormFile("file")
if err != nil {
http.Error(response, "missing file", http.StatusBadRequest)
return
}
defer file.Close()
isImg, contentType, err := isImage(file)
if err != nil || !isImg {
http.Error(response, "invalid file", http.StatusBadRequest)
return
}
if user.AvatarUrl != "" {
err = minio.Delete(ctx, user.AvatarUrl)
if err != nil {
http.Error(response, "internal server error", http.StatusInternalServerError)
return
}
}
key := minio.GetKey(minio.GetKeyOptions{
UserId: user.Id,
MimeType: contentType,
UploadType: minio.UserAvatar,
})
if err = minio.Upload(ctx, key, file, header.Size, contentType, map[string]string{
"originalName": header.Filename,
"uploaderId": user.Id.String(),
}); err != nil {
http.Error(response, "upload failed", http.StatusInternalServerError)
return
}
user.AvatarUrl = key
err = postgresql.UserUpdateProfile(ctx, user, types.UserProfileUpdateList{Avatar: true})
if err != nil {
http.Error(response, "internal server error", http.StatusInternalServerError)
return
}
response.WriteHeader(http.StatusAccepted)
}
func HandleUserModProfileBg(response http.ResponseWriter, request *http.Request) {
if !validCheckWithResponseOnFail(&response, request, profileBg) {
return
}
ctx := request.Context()
user, err := getUserByToken(ctx, request.Header.Get("token"))
if err != nil {
http.Error(response, "invalid token", http.StatusUnauthorized)
return
}
request.Body = http.MaxBytesReader(response, request.Body, int64(config.MaxRequestWithProfileBgBytes))
if err = request.ParseMultipartForm(int64(config.MaxRequestBytes)); err != nil {
http.Error(response, "invalid multipart form", http.StatusBadRequest)
return
}
file, header, err := request.FormFile("file")
if err != nil {
http.Error(response, "missing file", http.StatusBadRequest)
return
}
defer file.Close()
isImg, contentType, err := isImage(file)
if err != nil || !isImg {
http.Error(response, "invalid file", http.StatusBadRequest)
return
}
if user.ProfileBgUrl != "" {
err = minio.Delete(ctx, user.ProfileBgUrl)
if err != nil {
http.Error(response, "internal server error", http.StatusInternalServerError)
return
}
}
key := minio.GetKey(minio.GetKeyOptions{
UserId: user.Id,
MimeType: contentType,
UploadType: minio.UserProfileBg,
})
if err = minio.Upload(ctx, key, file, header.Size, contentType, map[string]string{
"originalName": header.Filename,
"uploaderId": user.Id.String(),
}); err != nil {
http.Error(response, "upload failed", http.StatusInternalServerError)
return
}
user.ProfileBgUrl = key
err = postgresql.UserUpdateProfile(ctx, user, types.UserProfileUpdateList{ProfileBg: true})
if err != nil {
http.Error(response, "internal server error", http.StatusInternalServerError)
return
}
response.WriteHeader(http.StatusAccepted)
}
func HandleUserGetUser(response http.ResponseWriter, request *http.Request) {
if !validCheckWithResponseOnFail(&response, request, normal) {
return