From 652ee6ad5d6c46f0d35c955ff7bb9bdac6240ca6 Mon Sep 17 00:00:00 2001 From: Elias Schneider Date: Wed, 19 Feb 2025 14:28:45 +0100 Subject: [PATCH] feat: add ability to upload a profile picture (#244) --- backend/go.mod | 6 +- backend/go.sum | 11 +- backend/internal/common/errors.go | 8 ++ .../internal/controller/user_controller.go | 73 +++++++++++++ .../controller/well_known_controller.go | 2 +- backend/internal/dto/app_config_dto.go | 1 + backend/internal/model/app_config.go | 1 + .../internal/service/app_config_service.go | 4 + backend/internal/service/ldap_service.go | 44 +++++++- backend/internal/service/oidc_service.go | 1 + backend/internal/service/user_service.go | 69 +++++++++++++ .../internal/utils/image/profile_picture.go | 96 ++++++++++++++++++ backend/resources/files.go | 2 +- .../resources/fonts/PlayfairDisplay-Bold.ttf | Bin 0 -> 193720 bytes .../{ => form}/auto-complete-input.svelte | 0 .../{ => form}/checkbox-with-label.svelte | 6 +- .../{ => form}/custom-claims-input.svelte | 2 +- .../components/{ => form}/file-input.svelte | 2 +- .../components/{ => form}/form-input.svelte | 2 +- .../form/profile-picture-settings.svelte | 83 +++++++++++++++ .../components/header/header-avatar.svelte | 17 +--- .../src/lib/components/header/header.svelte | 8 +- .../lib/components/ui/avatar/avatar.svelte | 2 +- frontend/src/lib/services/user-service.ts | 14 +++ .../lib/types/application-configuration.ts | 3 +- frontend/src/routes/settings/+layout.svelte | 42 ++++---- .../src/routes/settings/account/+page.svelte | 14 +++ .../settings/account/account-form.svelte | 2 +- .../application-image.svelte | 2 +- .../forms/app-config-email-form.svelte | 4 +- .../forms/app-config-general-form.svelte | 4 +- .../forms/app-config-ldap-form.svelte | 12 ++- .../oidc-callback-url-input.svelte | 2 +- .../oidc-clients/oidc-client-form.svelte | 6 +- .../admin/user-groups/[id]/+page.svelte | 2 +- .../admin/user-groups/user-group-form.svelte | 2 +- .../settings/admin/users/[id]/+page.svelte | 20 +++- .../settings/admin/users/user-form.svelte | 4 +- 38 files changed, 500 insertions(+), 73 deletions(-) create mode 100644 backend/internal/utils/image/profile_picture.go create mode 100644 backend/resources/fonts/PlayfairDisplay-Bold.ttf rename frontend/src/lib/components/{ => form}/auto-complete-input.svelte (100%) rename frontend/src/lib/components/{ => form}/checkbox-with-label.svelte (80%) rename frontend/src/lib/components/{ => form}/custom-claims-input.svelte (96%) rename frontend/src/lib/components/{ => form}/file-input.svelte (90%) rename frontend/src/lib/components/{ => form}/form-input.svelte (94%) create mode 100644 frontend/src/lib/components/form/profile-picture-settings.svelte diff --git a/backend/go.mod b/backend/go.mod index fb75934..aab4b92 100644 --- a/backend/go.mod +++ b/backend/go.mod @@ -4,6 +4,7 @@ go 1.23.1 require ( github.com/caarlos0/env/v11 v11.3.1 + github.com/disintegration/imaging v1.6.2 github.com/fxamacker/cbor/v2 v2.7.0 github.com/gin-gonic/gin v1.10.0 github.com/go-co-op/gocron/v2 v2.15.0 @@ -17,6 +18,7 @@ require ( github.com/mileusna/useragent v1.3.5 github.com/oschwald/maxminddb-golang/v2 v2.0.0-beta.2 golang.org/x/crypto v0.32.0 + golang.org/x/image v0.24.0 golang.org/x/time v0.9.0 gorm.io/driver/postgres v1.5.11 gorm.io/driver/sqlite v1.5.7 @@ -64,9 +66,9 @@ require ( golang.org/x/arch v0.13.0 // indirect golang.org/x/exp v0.0.0-20250106191152-7588d65b2ba8 // indirect golang.org/x/net v0.34.0 // indirect - golang.org/x/sync v0.10.0 // indirect + golang.org/x/sync v0.11.0 // indirect golang.org/x/sys v0.29.0 // indirect - golang.org/x/text v0.21.0 // indirect + golang.org/x/text v0.22.0 // indirect google.golang.org/protobuf v1.36.4 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/backend/go.sum b/backend/go.sum index 064eaba..90df780 100644 --- a/backend/go.sum +++ b/backend/go.sum @@ -22,6 +22,8 @@ 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/dhui/dktest v0.4.4 h1:+I4s6JRE1yGuqflzwqG+aIaMdgXIorCf5P98JnaAWa8= github.com/dhui/dktest v0.4.4/go.mod h1:4+22R4lgsdAXrDyaH4Nqx2JEz2hLp49MqQmm9HLCQhM= +github.com/disintegration/imaging v1.6.2 h1:w1LecBlG2Lnp8B3jk5zSuNqd7b4DXhcjwek1ei82L+c= +github.com/disintegration/imaging v1.6.2/go.mod h1:44/5580QXChDfwIclfc/PCwrr44amcmDAg8hxG0Ewe4= github.com/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5QvfrDyIgxBk= github.com/distribution/reference v0.6.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E= github.com/docker/docker v27.2.0+incompatible h1:Rk9nIVdfH3+Vz4cyI/uhbINhEZ/oLmc+CBXmH6fbNk4= @@ -211,6 +213,9 @@ golang.org/x/crypto v0.32.0 h1:euUpcYgM8WcP71gNpTqQCn6rC2t6ULUPiOzfWaXVVfc= golang.org/x/crypto v0.32.0/go.mod h1:ZnnJkOaASj8g0AjIduWNlq2NRxL0PlBrbKVyZ6V/Ugc= golang.org/x/exp v0.0.0-20250106191152-7588d65b2ba8 h1:yqrTHse8TCMW1M1ZCP+VAR/l0kKxwaAIqN/il7x4voA= golang.org/x/exp v0.0.0-20250106191152-7588d65b2ba8/go.mod h1:tujkw807nyEEAamNbDrEGzRav+ilXA7PCRAd6xsmwiU= +golang.org/x/image v0.0.0-20191009234506-e7c1f5e7dbb8/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= +golang.org/x/image v0.24.0 h1:AN7zRgVsbvmTfNyqIbbOraYL8mSwcKncEj8ofjgzcMQ= +golang.org/x/image v0.24.0/go.mod h1:4b/ITuLfqYq1hqZcjofwctIhi7sZh2WaCjvsBNjjya8= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= @@ -235,8 +240,9 @@ golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= -golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ= golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.11.0 h1:GGz8+XQP4FvTTrjZPzNKTMFtSXH80RAzG+5ghFPgK9w= +golang.org/x/sync v0.11.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -268,8 +274,9 @@ golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= -golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= +golang.org/x/text v0.22.0 h1:bofq7m3/HAFvbF51jz3Q9wLg3jkvSPuiZu/pD1XwgtM= +golang.org/x/text v0.22.0/go.mod h1:YRoo4H8PVmsu+E3Ou7cqLVH8oXWIHVoX0jqUWALQhfY= golang.org/x/time v0.9.0 h1:EsRrnYcQiGH+5FfbgvV4AP7qEZstoyrHB0DzarOQ4ZY= golang.org/x/time v0.9.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= diff --git a/backend/internal/common/errors.go b/backend/internal/common/errors.go index 4a0153f..dda1acf 100644 --- a/backend/internal/common/errors.go +++ b/backend/internal/common/errors.go @@ -211,3 +211,11 @@ func (e *UiConfigDisabledError) Error() string { return "The configuration can't be changed since the UI configuration is disabled" } func (e *UiConfigDisabledError) HttpStatusCode() int { return http.StatusForbidden } + +type InvalidUUIDError struct{} + +func (e *InvalidUUIDError) Error() string { + return "Invalid UUID" +} + +type InvalidEmailError struct{} diff --git a/backend/internal/controller/user_controller.go b/backend/internal/controller/user_controller.go index 0200acd..90883af 100644 --- a/backend/internal/controller/user_controller.go +++ b/backend/internal/controller/user_controller.go @@ -30,6 +30,11 @@ func NewUserController(group *gin.RouterGroup, jwtAuthMiddleware *middleware.Jwt group.PUT("/users/me", jwtAuthMiddleware.Add(false), uc.updateCurrentUserHandler) group.DELETE("/users/:id", jwtAuthMiddleware.Add(true), uc.deleteUserHandler) + group.GET("/users/:id/profile-picture.png", uc.getUserProfilePictureHandler) + group.GET("/users/me/profile-picture.png", jwtAuthMiddleware.Add(false), uc.getCurrentUserProfilePictureHandler) + group.PUT("/users/:id/profile-picture", jwtAuthMiddleware.Add(true), uc.updateUserProfilePictureHandler) + group.PUT("/users/me/profile-picture", jwtAuthMiddleware.Add(false), uc.updateUserProfilePictureHandler) + group.POST("/users/:id/one-time-access-token", jwtAuthMiddleware.Add(true), uc.createOneTimeAccessTokenHandler) group.POST("/one-time-access-token/:token", rateLimitMiddleware.Add(rate.Every(10*time.Second), 5), uc.exchangeOneTimeAccessTokenHandler) group.POST("/one-time-access-token/setup", uc.getSetupAccessTokenHandler) @@ -142,6 +147,74 @@ func (uc *UserController) updateCurrentUserHandler(c *gin.Context) { uc.updateUser(c, true) } +func (uc *UserController) getUserProfilePictureHandler(c *gin.Context) { + userID := c.Param("id") + + picture, size, err := uc.userService.GetProfilePicture(userID) + if err != nil { + c.Error(err) + return + } + + c.DataFromReader(http.StatusOK, size, "image/png", picture, nil) +} + +func (uc *UserController) getCurrentUserProfilePictureHandler(c *gin.Context) { + userID := c.GetString("userID") + + picture, size, err := uc.userService.GetProfilePicture(userID) + if err != nil { + c.Error(err) + return + } + + c.DataFromReader(http.StatusOK, size, "image/png", picture, nil) +} + +func (uc *UserController) updateUserProfilePictureHandler(c *gin.Context) { + userID := c.GetString("userID") + fileHeader, err := c.FormFile("file") + if err != nil { + c.Error(err) + return + } + file, err := fileHeader.Open() + if err != nil { + c.Error(err) + return + } + defer file.Close() + + if err := uc.userService.UpdateProfilePicture(userID, file); err != nil { + c.Error(err) + return + } + + c.Status(http.StatusNoContent) +} + +func (uc *UserController) updateCurrentUserProfilePictureHandler(c *gin.Context) { + userID := c.GetString("userID") + fileHeader, err := c.FormFile("file") + if err != nil { + c.Error(err) + return + } + file, err := fileHeader.Open() + if err != nil { + c.Error(err) + return + } + defer file.Close() + + if err := uc.userService.UpdateProfilePicture(userID, file); err != nil { + c.Error(err) + return + } + + c.Status(http.StatusNoContent) +} + func (uc *UserController) createOneTimeAccessTokenHandler(c *gin.Context) { var input dto.OneTimeAccessTokenCreateDto if err := c.ShouldBindJSON(&input); err != nil { diff --git a/backend/internal/controller/well_known_controller.go b/backend/internal/controller/well_known_controller.go index 48aeba7..3672d85 100644 --- a/backend/internal/controller/well_known_controller.go +++ b/backend/internal/controller/well_known_controller.go @@ -38,7 +38,7 @@ func (wkc *WellKnownController) openIDConfigurationHandler(c *gin.Context) { "end_session_endpoint": appUrl + "/api/oidc/end-session", "jwks_uri": appUrl + "/.well-known/jwks.json", "scopes_supported": []string{"openid", "profile", "email"}, - "claims_supported": []string{"sub", "given_name", "family_name", "name", "email", "email_verified", "preferred_username"}, + "claims_supported": []string{"sub", "given_name", "family_name", "name", "email", "email_verified", "preferred_username", "picture"}, "response_types_supported": []string{"code", "id_token"}, "subject_types_supported": []string{"public"}, "id_token_signing_alg_values_supported": []string{"RS256"}, diff --git a/backend/internal/dto/app_config_dto.go b/backend/internal/dto/app_config_dto.go index c0cbc9a..d3c0a7e 100644 --- a/backend/internal/dto/app_config_dto.go +++ b/backend/internal/dto/app_config_dto.go @@ -36,6 +36,7 @@ type AppConfigUpdateDto struct { LdapAttributeUserEmail string `json:"ldapAttributeUserEmail"` LdapAttributeUserFirstName string `json:"ldapAttributeUserFirstName"` LdapAttributeUserLastName string `json:"ldapAttributeUserLastName"` + LdapAttributeUserProfilePicture string `json:"ldapAttributeUserProfilePicture"` LdapAttributeGroupMember string `json:"ldapAttributeGroupMember"` LdapAttributeGroupUniqueIdentifier string `json:"ldapAttributeGroupUniqueIdentifier"` LdapAttributeGroupName string `json:"ldapAttributeGroupName"` diff --git a/backend/internal/model/app_config.go b/backend/internal/model/app_config.go index 7a834f8..ac47970 100644 --- a/backend/internal/model/app_config.go +++ b/backend/internal/model/app_config.go @@ -43,6 +43,7 @@ type AppConfig struct { LdapAttributeUserEmail AppConfigVariable LdapAttributeUserFirstName AppConfigVariable LdapAttributeUserLastName AppConfigVariable + LdapAttributeUserProfilePicture AppConfigVariable LdapAttributeGroupMember AppConfigVariable LdapAttributeGroupUniqueIdentifier AppConfigVariable LdapAttributeGroupName AppConfigVariable diff --git a/backend/internal/service/app_config_service.go b/backend/internal/service/app_config_service.go index b566749..5056201 100644 --- a/backend/internal/service/app_config_service.go +++ b/backend/internal/service/app_config_service.go @@ -173,6 +173,10 @@ var defaultDbConfig = model.AppConfig{ Key: "ldapAttributeUserLastName", Type: "string", }, + LdapAttributeUserProfilePicture: model.AppConfigVariable{ + Key: "ldapAttributeUserProfilePicture", + Type: "string", + }, LdapAttributeGroupMember: model.AppConfigVariable{ Key: "ldapAttributeGroupMember", Type: "string", diff --git a/backend/internal/service/ldap_service.go b/backend/internal/service/ldap_service.go index a8b652d..bc97d11 100644 --- a/backend/internal/service/ldap_service.go +++ b/backend/internal/service/ldap_service.go @@ -1,9 +1,14 @@ package service import ( + "bytes" "crypto/tls" + "encoding/base64" "fmt" + "io" "log" + "net/http" + "net/url" "strings" "github.com/go-ldap/ldap/v3" @@ -177,6 +182,7 @@ func (s *LdapService) SyncUsers() error { emailAttribute := s.appConfigService.DbConfig.LdapAttributeUserEmail.Value firstNameAttribute := s.appConfigService.DbConfig.LdapAttributeUserFirstName.Value lastNameAttribute := s.appConfigService.DbConfig.LdapAttributeUserLastName.Value + profilePictureAttribute := s.appConfigService.DbConfig.LdapAttributeUserProfilePicture.Value adminGroupAttribute := s.appConfigService.DbConfig.LdapAttributeAdminGroup.Value filter := s.appConfigService.DbConfig.LdapUserSearchFilter.Value @@ -189,6 +195,7 @@ func (s *LdapService) SyncUsers() error { emailAttribute, firstNameAttribute, lastNameAttribute, + profilePictureAttribute, } // Filters must start and finish with ()! @@ -237,9 +244,14 @@ func (s *LdapService) SyncUsers() error { if err != nil { log.Printf("Error syncing user %s: %s", newUser.Username, err) } - } + // Save profile picture + if pictureString := value.GetAttributeValue(profilePictureAttribute); pictureString != "" { + if err := s.SaveProfilePicture(databaseUser.ID, pictureString); err != nil { + log.Printf("Error saving profile picture for user %s: %s", newUser.Username, err) + } + } } // Get all LDAP users from the database @@ -260,3 +272,33 @@ func (s *LdapService) SyncUsers() error { } return nil } + +func (s *LdapService) SaveProfilePicture(userId string, pictureString string) error { + var reader io.Reader + + if _, err := url.ParseRequestURI(pictureString); err == nil { + // If the photo is a URL, download it + response, err := http.Get(pictureString) + if err != nil { + return fmt.Errorf("failed to download profile picture: %w", err) + } + defer response.Body.Close() + + reader = response.Body + + } else if decodedPhoto, err := base64.StdEncoding.DecodeString(pictureString); err == nil { + // If the photo is a base64 encoded string, decode it + reader = bytes.NewReader(decodedPhoto) + + } else { + // If the photo is a string, we assume that it's a binary string + reader = bytes.NewReader([]byte("pictureString")) + } + + // Update the profile picture + if err := s.userService.UpdateProfilePicture(userId, reader); err != nil { + return fmt.Errorf("failed to update profile picture: %w", err) + } + + return nil +} diff --git a/backend/internal/service/oidc_service.go b/backend/internal/service/oidc_service.go index 91b3c27..96967cc 100644 --- a/backend/internal/service/oidc_service.go +++ b/backend/internal/service/oidc_service.go @@ -401,6 +401,7 @@ func (s *OidcService) GetUserClaimsForClient(userID string, clientID string) (ma "family_name": user.LastName, "name": user.FullName(), "preferred_username": user.Username, + "picture": fmt.Sprintf("%s/api/users/%s/profile-picture.png", common.EnvConfig.AppURL, user.ID), } if strings.Contains(scope, "profile") { diff --git a/backend/internal/service/user_service.go b/backend/internal/service/user_service.go index 060b370..2166f02 100644 --- a/backend/internal/service/user_service.go +++ b/backend/internal/service/user_service.go @@ -3,8 +3,12 @@ package service import ( "errors" "fmt" + "github.com/google/uuid" + "github.com/pocket-id/pocket-id/backend/internal/utils/image" + "io" "log" "net/url" + "os" "strings" "time" @@ -48,6 +52,71 @@ func (s *UserService) GetUser(userID string) (model.User, error) { return user, err } +func (s *UserService) GetProfilePicture(userID string) (io.Reader, int64, error) { + // Validate the user ID to prevent directory traversal + if err := uuid.Validate(userID); err != nil { + return nil, 0, &common.InvalidUUIDError{} + } + + profilePicturePath := fmt.Sprintf("%s/profile-pictures/%s.png", common.EnvConfig.UploadPath, userID) + file, err := os.Open(profilePicturePath) + if err == nil { + // Get the file size + fileInfo, err := file.Stat() + if err != nil { + return nil, 0, err + } + return file, fileInfo.Size(), nil + } + + // If the file does not exist, return the default profile picture + user, err := s.GetUser(userID) + if err != nil { + return nil, 0, err + } + + defaultPicture, err := profilepicture.CreateDefaultProfilePicture(user.FirstName, user.LastName) + if err != nil { + return nil, 0, err + } + + return defaultPicture, int64(defaultPicture.Len()), nil +} + +func (s *UserService) UpdateProfilePicture(userID string, file io.Reader) error { + // Validate the user ID to prevent directory traversal + if err := uuid.Validate(userID); err != nil { + return &common.InvalidUUIDError{} + } + + // Convert the image to a smaller square image + profilePicture, err := profilepicture.CreateProfilePicture(file) + if err != nil { + return err + } + + // Ensure the directory exists + profilePictureDir := fmt.Sprintf("%s/profile-pictures", common.EnvConfig.UploadPath) + if err := os.MkdirAll(profilePictureDir, os.ModePerm); err != nil { + return err + } + + // Create the profile picture file + createdProfilePicture, err := os.Create(fmt.Sprintf("%s/%s.png", profilePictureDir, userID)) + if err != nil { + return err + } + defer createdProfilePicture.Close() + + // Copy the image to the file + _, err = io.Copy(createdProfilePicture, profilePicture) + if err != nil { + return err + } + + return nil +} + func (s *UserService) DeleteUser(userID string) error { var user model.User if err := s.db.Where("id = ?", userID).First(&user).Error; err != nil { diff --git a/backend/internal/utils/image/profile_picture.go b/backend/internal/utils/image/profile_picture.go new file mode 100644 index 0000000..3a7b6c1 --- /dev/null +++ b/backend/internal/utils/image/profile_picture.go @@ -0,0 +1,96 @@ +package profilepicture + +import ( + "bytes" + "fmt" + "github.com/disintegration/imaging" + "github.com/pocket-id/pocket-id/backend/resources" + "golang.org/x/image/font" + "golang.org/x/image/font/opentype" + "golang.org/x/image/math/fixed" + "image" + "image/color" + "io" + "strings" +) + +const profilePictureSize = 300 + +// CreateProfilePicture resizes the profile picture to a square +func CreateProfilePicture(file io.Reader) (*bytes.Buffer, error) { + img, err := imaging.Decode(file) + if err != nil { + return nil, fmt.Errorf("failed to decode image: %w", err) + } + + img = imaging.Fill(img, profilePictureSize, profilePictureSize, imaging.Center, imaging.Lanczos) + + var buf bytes.Buffer + err = imaging.Encode(&buf, img, imaging.PNG) + if err != nil { + return nil, fmt.Errorf("failed to encode image: %v", err) + } + + return &buf, nil +} + +// CreateDefaultProfilePicture creates a profile picture with the initials +func CreateDefaultProfilePicture(firstName, lastName string) (*bytes.Buffer, error) { + // Get the initials + initials := "" + if len(firstName) > 0 { + initials += string(firstName[0]) + } + if len(lastName) > 0 { + initials += string(lastName[0]) + } + initials = strings.ToUpper(initials) + + // Create a blank image with a white background + img := imaging.New(profilePictureSize, profilePictureSize, color.RGBA{R: 255, G: 255, B: 255, A: 255}) + + // Load the font + fontBytes, err := resources.FS.ReadFile("fonts/PlayfairDisplay-Bold.ttf") + if err != nil { + return nil, fmt.Errorf("failed to read font file: %w", err) + } + + // Parse the font + fontFace, err := opentype.Parse(fontBytes) + if err != nil { + return nil, fmt.Errorf("failed to parse font: %w", err) + } + + // Create a font.Face with a specific size + fontSize := 160.0 + face, err := opentype.NewFace(fontFace, &opentype.FaceOptions{ + Size: fontSize, + DPI: 72, + }) + if err != nil { + return nil, fmt.Errorf("failed to create font face: %w", err) + } + + // Create a drawer for the image + drawer := &font.Drawer{ + Dst: img, + Src: image.NewUniform(color.RGBA{R: 0, G: 0, B: 0, A: 255}), // Black text color + Face: face, + } + + // Center the initials + x := (profilePictureSize - font.MeasureString(face, initials).Ceil()) / 2 + y := (profilePictureSize-face.Metrics().Height.Ceil())/2 + face.Metrics().Ascent.Ceil() - 10 + drawer.Dot = fixed.P(x, y) + + // Draw the initials + drawer.DrawString(initials) + + var buf bytes.Buffer + err = imaging.Encode(&buf, img, imaging.PNG) + if err != nil { + return nil, fmt.Errorf("failed to encode image: %v", err) + } + + return &buf, nil +} diff --git a/backend/resources/files.go b/backend/resources/files.go index 9ef5328..6eb3d09 100644 --- a/backend/resources/files.go +++ b/backend/resources/files.go @@ -4,5 +4,5 @@ import "embed" // Embedded file systems for the project -//go:embed email-templates images migrations +//go:embed email-templates images migrations fonts var FS embed.FS diff --git a/backend/resources/fonts/PlayfairDisplay-Bold.ttf b/backend/resources/fonts/PlayfairDisplay-Bold.ttf new file mode 100644 index 0000000000000000000000000000000000000000..029a1a60e0d9cfd6bd1122f53c1644bc29924a5b GIT binary patch literal 193720 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 literal 0 HcmV?d00001 diff --git a/frontend/src/lib/components/auto-complete-input.svelte b/frontend/src/lib/components/form/auto-complete-input.svelte similarity index 100% rename from frontend/src/lib/components/auto-complete-input.svelte rename to frontend/src/lib/components/form/auto-complete-input.svelte diff --git a/frontend/src/lib/components/checkbox-with-label.svelte b/frontend/src/lib/components/form/checkbox-with-label.svelte similarity index 80% rename from frontend/src/lib/components/checkbox-with-label.svelte rename to frontend/src/lib/components/form/checkbox-with-label.svelte index 143ee3b..9cfbd2e 100644 --- a/frontend/src/lib/components/checkbox-with-label.svelte +++ b/frontend/src/lib/components/form/checkbox-with-label.svelte @@ -1,6 +1,6 @@ + +
+
+
+

Profile Picture

+ {#if isLdapUser} +

+ The profile picture is managed by the LDAP server and cannot be changed here. +

+ {:else} +

+ Click on the profile picture to upload a custom one from your files. +

+

The image should be in PNG or JPEG format.

+ {/if} +
+ {#if isLdapUser} + + + + {:else} + +
+ + + +
+ {#if isLoading} + + {:else} + + {/if} +
+
+
+ {/if} +
+
diff --git a/frontend/src/lib/components/header/header-avatar.svelte b/frontend/src/lib/components/header/header-avatar.svelte index d3e47c5..b428b0b 100644 --- a/frontend/src/lib/components/header/header-avatar.svelte +++ b/frontend/src/lib/components/header/header-avatar.svelte @@ -3,22 +3,10 @@ import * as DropdownMenu from '$lib/components/ui/dropdown-menu'; import WebAuthnService from '$lib/services/webauthn-service'; import userStore from '$lib/stores/user-store'; - import { createSHA256hash } from '$lib/utils/crypto-util'; import { LucideLogOut, LucideUser } from 'lucide-svelte'; const webauthnService = new WebAuthnService(); - let initials = $derived( - ($userStore!.firstName.charAt(0) + $userStore!.lastName?.charAt(0)).toUpperCase() - ); - - let gravatarURL: string | undefined = $state(); - if ($userStore) { - createSHA256hash($userStore.email).then((email) => { - gravatarURL = `https://www.gravatar.com/avatar/${email}?d=404`; - }); - } - async function logout() { await webauthnService.logout(); window.location.reload(); @@ -28,8 +16,7 @@ - - {initials} + @@ -39,7 +26,7 @@ {$userStore?.firstName} {$userStore?.lastName}

-

{$userStore?.email}

+

{$userStore?.email}

diff --git a/frontend/src/lib/components/header/header.svelte b/frontend/src/lib/components/header/header.svelte index d5f65de..7a1fcf0 100644 --- a/frontend/src/lib/components/header/header.svelte +++ b/frontend/src/lib/components/header/header.svelte @@ -5,9 +5,11 @@ import Logo from '../logo.svelte'; import HeaderAvatar from './header-avatar.svelte'; - const authUrls = ['/authorize', '/login', '/logout']; - let isAuthPage = $derived(!$page.error && authUrls.includes($page.url.pathname)); - + const authUrls = [/^\/authorize$/, /^\/login(?:\/.*)?$/, /^\/logout$/]; + + let isAuthPage = $derived( + !$page.error && authUrls.some((pattern) => pattern.test($page.url.pathname)) + );
diff --git a/frontend/src/lib/components/ui/avatar/avatar.svelte b/frontend/src/lib/components/ui/avatar/avatar.svelte index 9a12d65..b3da251 100644 --- a/frontend/src/lib/components/ui/avatar/avatar.svelte +++ b/frontend/src/lib/components/ui/avatar/avatar.svelte @@ -11,7 +11,7 @@ diff --git a/frontend/src/lib/services/user-service.ts b/frontend/src/lib/services/user-service.ts index ac98752..d946340 100644 --- a/frontend/src/lib/services/user-service.ts +++ b/frontend/src/lib/services/user-service.ts @@ -39,6 +39,20 @@ export default class UserService extends APIService { await this.api.delete(`/users/${id}`); } + async updateProfilePicture(userId: string, image: File) { + const formData = new FormData(); + formData.append('file', image!); + + await this.api.put(`/users/${userId}/profile-picture`, formData); + } + + async updateCurrentUsersProfilePicture(image: File) { + const formData = new FormData(); + formData.append('file', image!); + + await this.api.put('/users/me/profile-picture', formData); + } + async createOneTimeAccessToken(userId: string, expiresAt: Date) { const res = await this.api.post(`/users/${userId}/one-time-access-token`, { userId, diff --git a/frontend/src/lib/types/application-configuration.ts b/frontend/src/lib/types/application-configuration.ts index 4cac776..a5ea06d 100644 --- a/frontend/src/lib/types/application-configuration.ts +++ b/frontend/src/lib/types/application-configuration.ts @@ -31,6 +31,7 @@ export type AllAppConfig = AppConfig & { ldapAttributeUserEmail: string; ldapAttributeUserFirstName: string; ldapAttributeUserLastName: string; + ldapAttributeUserProfilePicture: string; ldapAttributeGroupMember: string; ldapAttributeGroupUniqueIdentifier: string; ldapAttributeGroupName: string; @@ -46,5 +47,5 @@ export type AppConfigRawResponse = { export type AppVersionInformation = { isUpToDate: boolean | null; newestVersion: string | null; - currentVersion: string + currentVersion: string; }; diff --git a/frontend/src/routes/settings/+layout.svelte b/frontend/src/routes/settings/+layout.svelte index e426c2a..36a10a1 100644 --- a/frontend/src/routes/settings/+layout.svelte +++ b/frontend/src/routes/settings/+layout.svelte @@ -33,41 +33,37 @@
-
+
-
-

+

Powered by toast.success('Profile picture updated successfully')) + .catch(axiosErrorToast); + } + async function createPasskey() { try { const opts = await webauthnService.getRegistrationOptions(); @@ -86,6 +94,12 @@ + + + + + +

diff --git a/frontend/src/routes/settings/account/account-form.svelte b/frontend/src/routes/settings/account/account-form.svelte index 4b21f01..fcfe9d1 100644 --- a/frontend/src/routes/settings/account/account-form.svelte +++ b/frontend/src/routes/settings/account/account-form.svelte @@ -1,5 +1,5 @@ @@ -62,6 +70,16 @@ + + + + + + - import CheckboxWithLabel from '$lib/components/checkbox-with-label.svelte'; - import FormInput from '$lib/components/form-input.svelte'; + import CheckboxWithLabel from '$lib/components/form/checkbox-with-label.svelte'; + import FormInput from '$lib/components/form/form-input.svelte'; import { Button } from '$lib/components/ui/button'; import appConfigStore from '$lib/stores/application-configuration-store'; import type { User, UserCreate } from '$lib/types/user.type';