Merge branch 'main' into v2

This commit is contained in:
Elias Schneider
2025-11-14 11:08:20 +01:00
7 changed files with 31 additions and 14 deletions

View File

@@ -2,11 +2,11 @@ name: Run Backend Linter
on:
push:
branches: [main]
branches: [main, breaking/**]
paths:
- "backend/**"
pull_request:
branches: [main]
branches: [main, breaking/**]
paths:
- "backend/**"

View File

@@ -1,13 +1,13 @@
name: E2E Tests
on:
push:
branches: [main]
branches: [main, breaking/**]
paths-ignore:
- "docs/**"
- "**.md"
- ".github/**"
pull_request:
branches: [main]
branches: [main, breaking/**]
paths-ignore:
- "docs/**"
- "**.md"

View File

@@ -2,7 +2,7 @@ name: Svelte Check
on:
push:
branches: [main]
branches: [main, breaking/**]
paths:
- "frontend/src/**"
- ".github/svelte-check-matcher.json"

View File

@@ -1,7 +1,7 @@
name: Unit Tests
on:
push:
branches: [main]
branches: [main, breaking/**]
paths:
- "backend/**"
pull_request:

View File

@@ -440,7 +440,7 @@ func (s *LdapService) SyncUsers(ctx context.Context, tx *gorm.DB, client *ldap.C
}
func (s *LdapService) saveProfilePicture(parentCtx context.Context, userId string, pictureString string) error {
var reader io.Reader
var reader io.ReadSeeker
_, err := url.ParseRequestURI(pictureString)
if err == nil {
@@ -460,7 +460,12 @@ func (s *LdapService) saveProfilePicture(parentCtx context.Context, userId strin
}
defer res.Body.Close()
reader = res.Body
data, err := io.ReadAll(res.Body)
if err != nil {
return fmt.Errorf("failed to read profile picture: %w", err)
}
reader = bytes.NewReader(data)
} else if decodedPhoto, err := base64.StdEncoding.DecodeString(pictureString); err == nil {
// If the photo is a base64 encoded string, decode it
reader = bytes.NewReader(decodedPhoto)

View File

@@ -159,7 +159,7 @@ func (s *UserService) GetUserGroups(ctx context.Context, userID string) ([]model
return user.UserGroups, nil
}
func (s *UserService) UpdateProfilePicture(ctx context.Context, userID string, file io.Reader) error {
func (s *UserService) UpdateProfilePicture(ctx context.Context, userID string, file io.ReadSeeker) error {
// Validate the user ID to prevent directory traversal
err := uuid.Validate(userID)
if err != nil {

View File

@@ -12,24 +12,36 @@ import (
"golang.org/x/image/font"
"golang.org/x/image/font/opentype"
"golang.org/x/image/math/fixed"
"golang.org/x/image/webp"
"github.com/pocket-id/pocket-id/backend/resources"
)
const profilePictureSize = 300
// CreateProfilePicture resizes the profile picture to a square
func CreateProfilePicture(file io.Reader) (io.ReadSeeker, error) {
// CreateProfilePicture resizes the profile picture to a square and encodes it as PNG
func CreateProfilePicture(file io.ReadSeeker) (io.ReadSeeker, error) {
// Attempt standard formats first
img, _, err := imageorient.Decode(file)
if err != nil {
return nil, fmt.Errorf("failed to decode image: %w", err)
if _, seekErr := file.Seek(0, io.SeekStart); seekErr != nil {
return nil, fmt.Errorf("failed to seek file: %w", seekErr)
}
// Try WebP
webpImg, webpErr := webp.Decode(file)
if webpErr != nil {
return nil, fmt.Errorf("failed to decode image: %w", err)
}
img = webpImg
}
// Resize to square
img = imaging.Fill(img, profilePictureSize, profilePictureSize, imaging.Center, imaging.Lanczos)
// Encode back to PNG
var buf bytes.Buffer
err = imaging.Encode(&buf, img, imaging.PNG)
if err != nil {
if err := imaging.Encode(&buf, img, imaging.PNG); err != nil {
return nil, fmt.Errorf("failed to encode image: %w", err)
}