mirror of
https://github.com/pocket-id/pocket-id.git
synced 2025-12-19 09:13:25 +03:00
Merge branch 'main' into v2
This commit is contained in:
4
.github/workflows/backend-linter.yml
vendored
4
.github/workflows/backend-linter.yml
vendored
@@ -2,11 +2,11 @@ name: Run Backend Linter
|
|||||||
|
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
branches: [main]
|
branches: [main, breaking/**]
|
||||||
paths:
|
paths:
|
||||||
- "backend/**"
|
- "backend/**"
|
||||||
pull_request:
|
pull_request:
|
||||||
branches: [main]
|
branches: [main, breaking/**]
|
||||||
paths:
|
paths:
|
||||||
- "backend/**"
|
- "backend/**"
|
||||||
|
|
||||||
|
|||||||
4
.github/workflows/e2e-tests.yml
vendored
4
.github/workflows/e2e-tests.yml
vendored
@@ -1,13 +1,13 @@
|
|||||||
name: E2E Tests
|
name: E2E Tests
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
branches: [main]
|
branches: [main, breaking/**]
|
||||||
paths-ignore:
|
paths-ignore:
|
||||||
- "docs/**"
|
- "docs/**"
|
||||||
- "**.md"
|
- "**.md"
|
||||||
- ".github/**"
|
- ".github/**"
|
||||||
pull_request:
|
pull_request:
|
||||||
branches: [main]
|
branches: [main, breaking/**]
|
||||||
paths-ignore:
|
paths-ignore:
|
||||||
- "docs/**"
|
- "docs/**"
|
||||||
- "**.md"
|
- "**.md"
|
||||||
|
|||||||
2
.github/workflows/svelte-check.yml
vendored
2
.github/workflows/svelte-check.yml
vendored
@@ -2,7 +2,7 @@ name: Svelte Check
|
|||||||
|
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
branches: [main]
|
branches: [main, breaking/**]
|
||||||
paths:
|
paths:
|
||||||
- "frontend/src/**"
|
- "frontend/src/**"
|
||||||
- ".github/svelte-check-matcher.json"
|
- ".github/svelte-check-matcher.json"
|
||||||
|
|||||||
2
.github/workflows/unit-tests.yml
vendored
2
.github/workflows/unit-tests.yml
vendored
@@ -1,7 +1,7 @@
|
|||||||
name: Unit Tests
|
name: Unit Tests
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
branches: [main]
|
branches: [main, breaking/**]
|
||||||
paths:
|
paths:
|
||||||
- "backend/**"
|
- "backend/**"
|
||||||
pull_request:
|
pull_request:
|
||||||
|
|||||||
@@ -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 {
|
func (s *LdapService) saveProfilePicture(parentCtx context.Context, userId string, pictureString string) error {
|
||||||
var reader io.Reader
|
var reader io.ReadSeeker
|
||||||
|
|
||||||
_, err := url.ParseRequestURI(pictureString)
|
_, err := url.ParseRequestURI(pictureString)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
@@ -460,7 +460,12 @@ func (s *LdapService) saveProfilePicture(parentCtx context.Context, userId strin
|
|||||||
}
|
}
|
||||||
defer res.Body.Close()
|
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 {
|
} else if decodedPhoto, err := base64.StdEncoding.DecodeString(pictureString); err == nil {
|
||||||
// If the photo is a base64 encoded string, decode it
|
// If the photo is a base64 encoded string, decode it
|
||||||
reader = bytes.NewReader(decodedPhoto)
|
reader = bytes.NewReader(decodedPhoto)
|
||||||
|
|||||||
@@ -159,7 +159,7 @@ func (s *UserService) GetUserGroups(ctx context.Context, userID string) ([]model
|
|||||||
return user.UserGroups, nil
|
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
|
// Validate the user ID to prevent directory traversal
|
||||||
err := uuid.Validate(userID)
|
err := uuid.Validate(userID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -12,24 +12,36 @@ import (
|
|||||||
"golang.org/x/image/font"
|
"golang.org/x/image/font"
|
||||||
"golang.org/x/image/font/opentype"
|
"golang.org/x/image/font/opentype"
|
||||||
"golang.org/x/image/math/fixed"
|
"golang.org/x/image/math/fixed"
|
||||||
|
"golang.org/x/image/webp"
|
||||||
|
|
||||||
"github.com/pocket-id/pocket-id/backend/resources"
|
"github.com/pocket-id/pocket-id/backend/resources"
|
||||||
)
|
)
|
||||||
|
|
||||||
const profilePictureSize = 300
|
const profilePictureSize = 300
|
||||||
|
|
||||||
// CreateProfilePicture resizes the profile picture to a square
|
// CreateProfilePicture resizes the profile picture to a square and encodes it as PNG
|
||||||
func CreateProfilePicture(file io.Reader) (io.ReadSeeker, error) {
|
func CreateProfilePicture(file io.ReadSeeker) (io.ReadSeeker, error) {
|
||||||
|
// Attempt standard formats first
|
||||||
img, _, err := imageorient.Decode(file)
|
img, _, err := imageorient.Decode(file)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
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)
|
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)
|
img = imaging.Fill(img, profilePictureSize, profilePictureSize, imaging.Center, imaging.Lanczos)
|
||||||
|
|
||||||
|
// Encode back to PNG
|
||||||
var buf bytes.Buffer
|
var buf bytes.Buffer
|
||||||
err = imaging.Encode(&buf, img, imaging.PNG)
|
if err := imaging.Encode(&buf, img, imaging.PNG); err != nil {
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("failed to encode image: %w", err)
|
return nil, fmt.Errorf("failed to encode image: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user