From 437a4f6e63e1f435a4d3a074b19f4cb9e32f33d1 Mon Sep 17 00:00:00 2001 From: alex Date: Sun, 8 Sep 2024 23:02:29 +0200 Subject: [PATCH] update user profile --- go.sum | 35 +++++++ modules/structs/users.go | 12 +++ modules/utils/globals.go | 11 ++- modules/utils/utils.go | 7 ++ routers/router/api/v1/lessons/lessons.go | 10 +- routers/router/api/v1/user/user.go | 121 +++++++++++++++++++++++ routers/router/router.go | 2 + socketclients/socketclients.go | 8 ++ 8 files changed, 200 insertions(+), 6 deletions(-) diff --git a/go.sum b/go.sum index 653fa5c..b915315 100644 --- a/go.sum +++ b/go.sum @@ -1,17 +1,25 @@ +filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA= +filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4= git.ex.umbach.dev/Alex/roese-utils v1.0.21 h1:ae1AHQh8UHJVLbpk5Gf4S5IP0EEWGD1JFIeX9cIcYcc= git.ex.umbach.dev/Alex/roese-utils v1.0.21/go.mod h1:hFcnKQl6nuGFEMCxK/eVQBUD6ixBFlAaiy4E2aQqUL8= git.ex.umbach.dev/LMS/libcore v1.0.6 h1:Af+2jD4aC3+4qMgSmTn4nvRosAS5ETTX9JR3gznlGPI= git.ex.umbach.dev/LMS/libcore v1.0.6/go.mod h1:BvbMJWYQ83dblDAB4ooLfwuorjdy6G3txdOrjRfIKPA= github.com/andybalholm/brotli v1.0.5 h1:8uQZIdzKmjc/iuPu7O2ioW48L81FgatrcpfFmiq/cCs= github.com/andybalholm/brotli v1.0.5/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig= +github.com/andybalholm/brotli v1.1.0 h1:eLKJA0d02Lf0mVpIDgYnqXcUn0GqVmEFny3VuID1U3M= +github.com/andybalholm/brotli v1.1.0/go.mod h1:sms7XGricyQI9K10gOSf56VKKWS4oLer58Q+mhRPtnY= github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/fasthttp/websocket v1.5.3 h1:TPpQuLwJYfd4LJPXvHDYPMFWbLjsT91n3GpWtCQtdek= github.com/fasthttp/websocket v1.5.3/go.mod h1:46gg/UBmTU1kUaTcwQXpUxtRwG2PvIZYeA8oL6vF3Fs= +github.com/fasthttp/websocket v1.5.10 h1:bc7NIGyrg1L6sd5pRzCIbXpro54SZLEluZCu0rOpcN4= +github.com/fasthttp/websocket v1.5.10/go.mod h1:BwHeuXGWzCW1/BIKUKD3+qfCl+cTdsHu/f243NcAI/Q= github.com/gabriel-vasile/mimetype v1.4.2 h1:w5qFW6JKBz9Y393Y4q372O9A7cUSequkh1Q7OhCmWKU= github.com/gabriel-vasile/mimetype v1.4.2/go.mod h1:zApsH/mKG4w07erKIaJPFiX0Tsq9BFQgN3qGY5GnNgA= +github.com/gabriel-vasile/mimetype v1.4.5 h1:J7wGKdGu33ocBOhGy0z653k/lFKLFDPJMG8Gql0kxn4= +github.com/gabriel-vasile/mimetype v1.4.5/go.mod h1:ibHel+/kbxn9x2407k1izTA1S81ku1z/DlgOW2QE0M4= github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s= github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA= @@ -20,8 +28,12 @@ github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJn github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY= github.com/go-playground/validator/v10 v10.15.5 h1:LEBecTWb/1j5TNY1YYG2RcOUN3R7NLylN+x8TTueE24= github.com/go-playground/validator/v10 v10.15.5/go.mod h1:9iXMNT7sEkjXb0I+enO7QXmzG6QCsPWY4zveKFVRSyU= +github.com/go-playground/validator/v10 v10.22.0 h1:k6HsTZ0sTnROkhS//R0O+55JgM8C4Bx7ia+JlgcnOao= +github.com/go-playground/validator/v10 v10.22.0/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM= github.com/go-sql-driver/mysql v1.7.0 h1:ueSltNNllEqE3qcWBTD0iQd3IpL/6U+mJxLkazJ7YPc= github.com/go-sql-driver/mysql v1.7.0/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI= +github.com/go-sql-driver/mysql v1.8.1 h1:LedoTUt/eveggdHS9qUFC1EFSa8bU2+1pZjSRpvNJ1Y= +github.com/go-sql-driver/mysql v1.8.1/go.mod h1:wEBSXgmK//2ZFJyE+qWnIsVGmvmEKlqwuVSjsCm7DZg= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/gofiber/fiber/v2 v2.52.5 h1:tWoP1MJQjGEe4GB5TUGOi7P2E0ZMMRx5ZTG4rT+yGMo= github.com/gofiber/fiber/v2 v2.52.5/go.mod h1:KEOE+cXMhXG0zHc9d8+E38hoX+ZN7bhOtgeF2oT6jrQ= @@ -37,8 +49,12 @@ github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0= github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4= github.com/klauspost/compress v1.17.0 h1:Rnbp4K9EjcDuVuHtd0dgA4qNuv9yKDYKK1ulpJwgrqM= github.com/klauspost/compress v1.17.0/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= +github.com/klauspost/compress v1.17.9 h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA= +github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw= github.com/leodido/go-urn v1.2.4 h1:XlAE/cm/ms7TE/VMVoduSpNBoyc2dOxHs5MZSwAN63Q= github.com/leodido/go-urn v1.2.4/go.mod h1:7ZrI8mTSeBSHl/UaRyKQW1qZeMgak41ANeCNaVckg+4= +github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ= +github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI= github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= @@ -47,16 +63,24 @@ github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWE github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U= github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= +github.com/mattn/go-runewidth v0.0.16 h1:E5ScNMtiwvlvB5paMFdw9p4kSQzbXFikJ5SQO6TULQc= +github.com/mattn/go-runewidth v0.0.16/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY= github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= +github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ= +github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= github.com/rs/zerolog v1.31.0 h1:FcTR3NnLWW+NnTwwhFWiJSZr4ECLpqCm6QsEnyvbV4A= github.com/rs/zerolog v1.31.0/go.mod h1:/7mN4D5sKwJLZQ2b/znpjC3/GQWY/xaDXUM0kKWRHss= +github.com/rs/zerolog v1.33.0 h1:1cU2KZkvPxNyfgEmhHAz/1A9Bz+llsdYzklWFzgp0r8= +github.com/rs/zerolog v1.33.0/go.mod h1:/7mN4D5sKwJLZQ2b/znpjC3/GQWY/xaDXUM0kKWRHss= github.com/savsgio/gotils v0.0.0-20230208104028-c358bd845dee h1:8Iv5m6xEo1NR1AvpV+7XmhI4r39LGNzwUL4YpMuL5vk= github.com/savsgio/gotils v0.0.0-20230208104028-c358bd845dee/go.mod h1:qwtSXrKuJh/zsFQ12yEE89xfCrGKK63Rr7ctU/uCo4g= +github.com/savsgio/gotils v0.0.0-20240704082632-aef3928b8a38 h1:D0vL7YNisV2yqE55+q0lFuGse6U8lxlg7fYTctlT5Gc= +github.com/savsgio/gotils v0.0.0-20240704082632-aef3928b8a38/go.mod h1:sM7Mt7uEoCeFSCBM+qBrqvEo+/9vdmj19wzp3yzUhmg= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= @@ -64,23 +88,34 @@ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8= github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= github.com/valyala/fasthttp v1.51.0 h1:8b30A5JlZ6C7AS81RsWjYMQmrZG6feChmgAolCl1SqA= github.com/valyala/fasthttp v1.51.0/go.mod h1:oI2XroL+lI7vdXyYoQk03bXBThfFl2cVdIA3Xl7cH8g= +github.com/valyala/fasthttp v1.55.0 h1:Zkefzgt6a7+bVKHnu/YaYSOPfNYNisSVBo/unVCf8k8= +github.com/valyala/fasthttp v1.55.0/go.mod h1:NkY9JtkrpPKmgwV3HTaS2HWaJss9RSIsRVfcxxoHiOM= github.com/valyala/tcplisten v1.0.0 h1:rBHj/Xf+E1tRGZyWIWwJDiRY0zc1Js+CV5DqwacVSA8= github.com/valyala/tcplisten v1.0.0/go.mod h1:T0xQ8SeCZGxckz9qRXTfG43PvQ/mcWh7FwZEA7Ioqkc= golang.org/x/crypto v0.14.0 h1:wBqGXzWJW6m1XrIKlAH0Hs1JJ7+9KBwnIO8v66Q9cHc= golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4= +golang.org/x/crypto v0.27.0 h1:GXm2NjJrPaiv/h1tb2UH8QfgC/hOf/+z0p6PT8o1w7A= +golang.org/x/crypto v0.27.0/go.mod h1:1Xngt8kV6Dvbssa53Ziq6Eqn0HqbZi5Z6R0ZpwQzt70= golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM= golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= +golang.org/x/net v0.29.0 h1:5ORfpBpCs4HzDYoodCDBbwHzdR5UrLBZ3sOnUJmFoHo= +golang.org/x/net v0.29.0/go.mod h1:gLkgy8jTGERgjzMic6DS9+SP0ajcu6Xu3Orq/SpETg0= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc= golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34= +golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc= golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= +golang.org/x/text v0.18.0 h1:XvMDiNzPAl0jr17s6W9lcaIhGUfUORdGCNsuLmPG224= +golang.org/x/text v0.18.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= diff --git a/modules/structs/users.go b/modules/structs/users.go index 606c463..d129e4d 100644 --- a/modules/structs/users.go +++ b/modules/structs/users.go @@ -26,6 +26,7 @@ type TeamMember struct { Online bool `gorm:"-"` } +// swagger:model CreateTeamMemberRequest type CreateTeamMemberRequest struct { FirstName string LastName string @@ -34,10 +35,21 @@ type CreateTeamMemberRequest struct { Password string } +// swagger:model TeamMemberUserIdParam type TeamMemberUserIdParam struct { MemberId string } +// swagger:model UpdateTeamMemberRoleRequest type UpdateTeamMemberRoleRequest struct { RoleId string } + +// swagger:model CreateOrganizationResponse +type GetUserProfileResponse struct { + ProfilePictureUrl string + FirstName string + LastName string + Email string + RoleId string +} diff --git a/modules/utils/globals.go b/modules/utils/globals.go index 7f109a4..b73bdfd 100644 --- a/modules/utils/globals.go +++ b/modules/utils/globals.go @@ -96,6 +96,7 @@ const ( SendCmdLessonContentUpdated = 14 SendCmdLessonContentUpdatedPosition = 15 SendCmdLessonContentFileUpdated = 16 + SendCmdUserProfilePictureUpdated = 17 ) // commands received from websocket clients @@ -104,11 +105,11 @@ const ( ) const ( - SubscribedTopicLessons = "/lessons" - SubscribedTopicTeam = "/team" - SubscribedTopicRoles = "/roles" - SubscribedTopicSettings = "/settings" - SubscribedTopicAccount = "/account" + SubscribedTopicLessons = "/lessons" + SubscribedTopicTeam = "/team" + SubscribedTopicRoles = "/roles" + SubscribedTopicSettings = "/settings" + SubscribedTopicUserProfile = "/user-profile" ) func SubscribedTopicLessonsId(organizationId string) string { diff --git a/modules/utils/utils.go b/modules/utils/utils.go index 21843ed..90ec387 100644 --- a/modules/utils/utils.go +++ b/modules/utils/utils.go @@ -148,3 +148,10 @@ func GetFullImagePath(organizationId string, lessonId string) (databasePath stri fmt.Sprintf( "%s/o/%s/l/%s/", config.Cfg.FolderPaths.PublicStatic, organizationId, lessonId) } + +func GetFullImagePathForUserProfilePicture(organizationId string) (databasePath string, publicPath string) { + return fmt.Sprintf( + "o/%s/u/", organizationId), + fmt.Sprintf( + "%s/o/%s/u/", config.Cfg.FolderPaths.PublicStatic, organizationId) +} diff --git a/routers/router/api/v1/lessons/lessons.go b/routers/router/api/v1/lessons/lessons.go index 2cbc8ed..0ff6fa7 100644 --- a/routers/router/api/v1/lessons/lessons.go +++ b/routers/router/api/v1/lessons/lessons.go @@ -300,6 +300,12 @@ func UpdateLessonPreviewThumbnail(c *fiber.Ctx) error { return c.SendStatus(fiber.StatusInternalServerError) } + if err := c.SaveFile(fileHeader, publicPath+fileName); err != nil { + return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{ + "error": "Failed to save file", + }) + } + socketclients.BroadcastMessageToTopics( c.Locals("organizationId").(string), []string{utils.SubscribedTopicLessons, utils.SubscribedTopicLessonsEditorId(params.LessonId)}, @@ -315,7 +321,9 @@ func UpdateLessonPreviewThumbnail(c *fiber.Ctx) error { }, ) - return c.SaveFile(fileHeader, publicPath+fileName) + return c.JSON(fiber.Map{ + "status": "success", + }) } func UpdateLessonState(c *fiber.Ctx) error { diff --git a/routers/router/api/v1/user/user.go b/routers/router/api/v1/user/user.go index a00006b..0701b31 100644 --- a/routers/router/api/v1/user/user.go +++ b/routers/router/api/v1/user/user.go @@ -1 +1,122 @@ package user + +import ( + "strings" + + "git.ex.umbach.dev/LMS/libcore/models" + "github.com/gofiber/fiber/v2" + "github.com/google/uuid" + "lms.de/backend/modules/database" + "lms.de/backend/modules/structs" + "lms.de/backend/modules/utils" + "lms.de/backend/socketclients" +) + +func GetUserProfile(c *fiber.Ctx) error { + // swagger:operation GET /user/profile user getUserProfile + // --- + // summary: Get user profile + // consumes: + // - application/json + // produces: + // - application/json + // responses: + // '200': + // description: User profile fetched successfully + // schema: + // "$ref": "#/definitions/GetUserProfileResponse" + // '400': + // description: Invalid request body + // '500': + // description: Failed to fetch account + + var user structs.GetUserProfileResponse + + database.DB.Model(&models.User{}).Where("id = ?", c.Locals("userId").(string)).First(&user) + + return c.JSON(user) +} + +func UpdateUserProfilePicture(c *fiber.Ctx) error { + // swagger:operation POST /user/profile/picture user updateUserProfilePicture + // --- + // summary: Update user profile picture + // consumes: + // - application/json + // produces: + // - application/json + // parameters: + // - name: file + // in: formData + // type: file + // required: true + // responses: + // '200': + // description: Profile picture updated successfully + // schema: + // type: string + // '400': + // description: Invalid request body + // '500': + // description: Failed to update profile picture + + fileHeader, err := c.FormFile("file") + + if err != nil { + return c.SendStatus(fiber.StatusBadRequest) + } + + if fileHeader.Size > utils.MaxImageSize { + return c.SendStatus(fiber.StatusBadRequest) + } + + if !utils.IsFileTypeAllowed(fileHeader.Header.Get("Content-Type"), utils.AcceptedImageFileTypes) { + return c.SendStatus(fiber.StatusBadRequest) + } + + // get current profile picture + + user := models.User{} + + if err := database.DB.Model(&models.User{}).Select("profile_picture_url").Where("id = ?", c.Locals("userId").(string)).First(&user).Error; err != nil { + return c.SendStatus(fiber.StatusInternalServerError) + } + + // delete current profile picture + + if user.ProfilePictureUrl != "" { + utils.DeleteFile(user.ProfilePictureUrl) + } + + fileName := uuid.New().String() + "." + strings.Split(fileHeader.Header["Content-Type"][0], "/")[1] + + databasePath, publicPath := utils.GetFullImagePathForUserProfilePicture(c.Locals("organizationId").(string)) + + utils.CreateFolderStructureIfNotExists(publicPath) + + profilePictureUrl := databasePath + fileName + + if err := database.DB.Model(&models.User{}).Where("id = ?", c.Locals("userId").(string)).Update("profile_picture_url", profilePictureUrl).Error; err != nil { + return c.SendStatus(fiber.StatusInternalServerError) + } + + if err := c.SaveFile(fileHeader, publicPath+fileName); err != nil { + return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{ + "error": "Failed to save file", + }) + } + + socketclients.SendMessageToUserWithTopicExceptBrowserTabSession( + c.Locals("userId").(string), + utils.SubscribedTopicUserProfile, + c.Locals("browserTabSession").(string), + structs.SendSocketMessage{ + Cmd: utils.SendCmdUserProfilePictureUpdated, + Body: profilePictureUrl, + }, + ) + + return c.JSON(fiber.Map{ + "Data": databasePath + fileName, + }) +} diff --git a/routers/router/router.go b/routers/router/router.go index 4c0d44d..80e74d2 100644 --- a/routers/router/router.go +++ b/routers/router/router.go @@ -35,6 +35,8 @@ func SetupRoutes(app *fiber.App) { u := v1.Group("/user") u.Post("/auth/login", handleOrganizationSubdomain, user.UserLogin) + u.Get("/profile", handleOrganizationSubdomain, requestAccessValidation, user.GetUserProfile) + u.Post("/profile/picture", handleOrganizationSubdomain, requestAccessValidation, user.UpdateUserProfilePicture) l := v1.Group("/lessons") l.Get("/", handleOrganizationSubdomain, requestAccessValidation, lessons.GetLessons) diff --git a/socketclients/socketclients.go b/socketclients/socketclients.go index c7fea33..e23f493 100644 --- a/socketclients/socketclients.go +++ b/socketclients/socketclients.go @@ -85,3 +85,11 @@ func IsUserConnected(userId string) bool { return false } + +func SendMessageToUserWithTopicExceptBrowserTabSession(userId string, topic string, browserTabSession string, sendSocketMessage structs.SendSocketMessage) { + for _, client := range cache.GetSocketClients() { + if client.UserId == userId && client.SubscribedTopic == topic && client.BrowserTabSession != browserTabSession { + client.SendMessage(sendSocketMessage) + } + } +}