chore: update Francis to rc.2

Also replaces the direct use of the github.com/google/uuid package with the uuid package from the standard library in Go 1.27 (package remains as a transitive dep)
This commit is contained in:
ItalyPaleAle
2026-08-31 07:47:09 +02:00
parent 7c79a9e14b
commit 0c79ae0ea6
15 changed files with 43 additions and 41 deletions

View File

@@ -22,8 +22,7 @@ require (
github.com/go-playground/validator/v10 v10.30.3
github.com/go-webauthn/webauthn v0.17.4
github.com/golang-migrate/migrate/v4 v4.19.1
github.com/google/uuid v1.6.0
github.com/italypaleale/francis v0.1.0-rc.1
github.com/italypaleale/francis v0.1.0-rc.2
github.com/italypaleale/go-kit v1.0.0
github.com/italypaleale/go-sql-utils v0.3.6
github.com/jackc/pgx/v5 v5.10.0
@@ -122,6 +121,7 @@ require (
github.com/google/go-github/v39 v39.2.0 // indirect
github.com/google/go-querystring v1.2.0 // indirect
github.com/google/go-tpm v0.9.8 // indirect
github.com/google/uuid v1.6.0 // indirect
github.com/gorilla/websocket v1.5.3 // indirect
github.com/grpc-ecosystem/grpc-gateway/v2 v2.29.0 // indirect
github.com/h2non/filetype v1.1.3 // indirect

View File

@@ -241,8 +241,8 @@ github.com/hashicorp/golang-lru/v2 v2.0.7 h1:a+bsQ5rvGLjzHuww6tVxozPZFVghXaHOwFs
github.com/hashicorp/golang-lru/v2 v2.0.7/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM=
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
github.com/italypaleale/francis v0.1.0-rc.1 h1:zRDkHPxiAYOQTuGegMlWVs/TCIsoLblcd/xoM/ItNP0=
github.com/italypaleale/francis v0.1.0-rc.1/go.mod h1:4ce0qAv9OoDY3FxsIVD46aHzMbqyixlucsNKcSyaNl4=
github.com/italypaleale/francis v0.1.0-rc.2 h1:GD8M9x4gVXWic5W3QwbA+NvhAl3uLW1/gg2OGje7Ix0=
github.com/italypaleale/francis v0.1.0-rc.2/go.mod h1:vtO32inBhTtYQ+2SjnLX81hIy+x7n8xnUESj7XK4yeQ=
github.com/italypaleale/go-kit v1.0.0 h1:c+SaYHTaoZzTgbPXhSbNVdNRkNdNhE0YljBWWoPTdKI=
github.com/italypaleale/go-kit v1.0.0/go.mod h1:wg4UsIbsbtDiVqUjJdo/tO9lXo0OXBuwPOpSJ+u+1jI=
github.com/italypaleale/go-sql-utils v0.3.6 h1:ND14osePZFhn717qqI+nuH2blxKLTcYqWYSAG9anVDg=

View File

@@ -5,8 +5,8 @@ import (
"errors"
"fmt"
"time"
"uuid"
"github.com/google/uuid"
"gorm.io/gorm"
)
@@ -14,7 +14,7 @@ import (
// If no instance ID exists yet, a new one is generated and persisted atomically
func Load(parentCtx context.Context, db *gorm.DB) (string, error) {
// Candidate value used only if there's no instance ID stored yet
newInstanceID := uuid.NewString()
newInstanceID := uuid.NewV4().String()
// We use a raw query because gorm can't build it for us in this atomic way
// The syntax is valid for both SQLite and Postgres

View File

@@ -3,8 +3,8 @@ package instanceid
import (
"sync"
"testing"
"uuid"
"github.com/google/uuid"
"github.com/stretchr/testify/require"
"gorm.io/gorm"
@@ -138,7 +138,7 @@ func TestMigrateFromAppConfig(t *testing.T) {
}
t.Run("moves an existing instance ID from app_config_variables into the kv table", func(t *testing.T) {
legacyID := uuid.NewString()
legacyID := uuid.NewV4().String()
db := testutils.NewDatabaseForTestWithMigrationSeed(t, versionBeforeMove, seedAppConfigInstanceID(legacyID))
// The migration should have copied the value into the kv table under the "instance_id" key
@@ -160,7 +160,7 @@ func TestMigrateFromAppConfig(t *testing.T) {
})
t.Run("keeps the existing kv value when both tables have an instance ID", func(t *testing.T) {
legacyID := uuid.NewString()
legacyID := uuid.NewV4().String()
db := testutils.NewDatabaseForTestWithMigrationSeed(t, versionBeforeMove, func(t *testing.T, db *gorm.DB) {
t.Helper()
// An instance ID is already present in the kv table before the move runs

View File

@@ -14,9 +14,9 @@ import (
"strings"
"time"
"unicode/utf8"
"uuid"
"github.com/go-ldap/ldap/v3"
"github.com/google/uuid"
"golang.org/x/text/unicode/norm"
"gorm.io/gorm"
@@ -735,9 +735,7 @@ func convertLdapIdToString(ldapId string) string {
// Try to parse as binary UUID (16 bytes)
if len(ldapId) == 16 {
if parsedUUID, err := uuid.FromBytes([]byte(ldapId)); err == nil {
return parsedUUID.String()
}
return uuid.UUID([]byte(ldapId)).String()
}
// As a last resort, encode as base64 to make it UTF-8 safe

View File

@@ -10,14 +10,15 @@ import (
"strings"
"time"
"unicode"
"uuid"
"github.com/gin-gonic/gin"
"github.com/gin-gonic/gin/binding"
"github.com/go-playground/validator/v10"
"github.com/google/uuid"
"go.opentelemetry.io/otel/trace"
"github.com/pocket-id/pocket-id/backend/internal/apperror"
"github.com/pocket-id/pocket-id/backend/internal/dto"
"go.opentelemetry.io/otel/trace"
)
const requestIDHeader = "X-Request-ID"
@@ -81,7 +82,7 @@ type classifiedError struct {
// Add records a request ID before executing the request and serializes the first returned error afterward
func (m *ErrorHandlerMiddleware) Add() gin.HandlerFunc {
return func(c *gin.Context) {
requestID := uuid.NewString()
requestID := uuid.NewV4().String()
c.Set(requestIDContextKey{}, requestID)
c.Header(requestIDHeader, requestID)

View File

@@ -2,8 +2,8 @@ package model
import (
"time"
"uuid"
"github.com/google/uuid"
datatype "github.com/pocket-id/pocket-id/backend/internal/model/types"
"gorm.io/gorm"
)
@@ -16,7 +16,7 @@ type Base struct {
func (b *Base) BeforeCreate(_ *gorm.DB) (err error) {
if b.ID == "" {
b.ID = uuid.New().String()
b.ID = uuid.NewV4().String()
}
b.CreatedAt = datatype.DateTime(time.Now())
return

View File

@@ -3,8 +3,8 @@ package oidc
import (
"encoding/json"
"time"
"uuid"
"github.com/google/uuid"
"github.com/ory/fosite"
fositeoauth2 "github.com/ory/fosite/handler/oauth2"
"github.com/ory/fosite/handler/openid"
@@ -48,7 +48,7 @@ func NewAuthenticatedSession(subject, authenticationMethod string, authenticatio
session.Claims.Subject = subject
session.Claims.AuthTime = authenticationTime.UTC()
session.Claims.RequestedAt = requestedAt.UTC()
session.Claims.JTI = uuid.NewString()
session.Claims.JTI = uuid.NewV4().String()
return session
}

View File

@@ -12,9 +12,9 @@ import (
"log/slog"
"path"
"time"
"uuid"
"github.com/go-webauthn/webauthn/protocol"
"github.com/google/uuid"
"github.com/italypaleale/francis/actor"
"github.com/italypaleale/francis/host/local"
"github.com/lestrrat-go/jwx/v3/jwa"
@@ -920,7 +920,7 @@ func (s *TestService) SignAccessToken(ctx context.Context, userID, clientID stri
session := fositeTokenSession{
Kind: "access_token",
RequestID: "e2e-access-" + uuid.NewString(),
RequestID: "e2e-access-" + uuid.NewV4().String(),
UserID: userID,
ClientID: clientID,
AuthenticationMethod: AuthenticationMethodPhishingResistant,
@@ -1022,7 +1022,7 @@ func (s *TestService) SignExternalIdPToken(iss, sub, aud string) (string, error)
Subject(sub).
Expiration(now.Add(time.Hour)).
IssuedAt(now).
JwtID(uuid.NewString()).
JwtID(uuid.NewV4().String()).
Issuer(iss).
Audience([]string{aud}).
Build()

View File

@@ -6,8 +6,8 @@ import (
"errors"
"fmt"
"time"
"uuid"
"github.com/google/uuid"
"github.com/lestrrat-go/jwx/v3/jwa"
"github.com/lestrrat-go/jwx/v3/jwk"
"github.com/lestrrat-go/jwx/v3/jwt"
@@ -188,7 +188,7 @@ func (s *JwtService) GenerateAccessToken(user model.User, authenticationMethod s
Expiration(now.Add(sessionDuration)).
IssuedAt(now).
Issuer(s.envConfig.AppURL).
JwtID(uuid.New().String()).
JwtID(uuid.NewV4().String()).
Build()
if err != nil {
return "", fmt.Errorf("failed to build token: %w", err)

View File

@@ -13,8 +13,8 @@ import (
"slices"
"strings"
"time"
"uuid"
"github.com/google/uuid"
"gorm.io/gorm"
"gorm.io/gorm/clause"
@@ -387,7 +387,7 @@ func (s *OidcService) CreateClientSecret(ctx context.Context, clientID string, i
// Only the hash and a short prefix are persisted, so this is the last time the value is available
secret := model.OidcClientSecret{
ID: uuid.New().String(),
ID: uuid.NewV4().String(),
Algorithm: model.OidcClientSecretHashSHA256,
Hash: utils.CreateSha256Hash(clientSecret),
Prefix: clientSecretPrefix(clientSecret),

View File

@@ -11,8 +11,8 @@ import (
"log/slog"
"path"
"time"
"uuid"
"github.com/google/uuid"
"gorm.io/gorm"
"gorm.io/gorm/clause"
@@ -88,7 +88,8 @@ func (s *UserService) getUserInternal(ctx context.Context, userID string, tx *go
func (s *UserService) GetProfilePicture(ctx context.Context, userID string) (io.ReadCloser, int64, error) {
// Validate the user ID to prevent directory traversal
if err := uuid.Validate(userID); err != nil {
_, err := uuid.Parse(userID)
if err != nil {
return nil, 0, apperror.InvalidUserID()
}
@@ -167,7 +168,7 @@ func (s *UserService) GetUserGroups(ctx context.Context, userID string) ([]model
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)
_, err := uuid.Parse(userID)
if err != nil {
return apperror.InvalidUserID()
}
@@ -639,16 +640,19 @@ func (s *UserService) checkDuplicatedFields(ctx context.Context, user model.User
// ResetProfilePicture deletes a user's custom profile picture
func (s *UserService) ResetProfilePicture(ctx context.Context, userID string) error {
// Validate the user ID to prevent directory traversal
if err := uuid.Validate(userID); err != nil {
_, err := uuid.Parse(userID)
if err != nil {
return apperror.InvalidUserID()
}
if _, err := s.GetUser(ctx, userID); err != nil {
_, err = s.GetUser(ctx, userID)
if err != nil {
return err
}
profilePicturePath := path.Join("profile-pictures", userID+".png")
if err := s.fileStorage.Delete(ctx, profilePicturePath); err != nil {
err = s.fileStorage.Delete(ctx, profilePicturePath)
if err != nil {
return fmt.Errorf("failed to delete profile picture: %w", err)
}
return nil

View File

@@ -4,8 +4,8 @@ import (
"encoding/json"
"strings"
"testing"
"uuid"
"github.com/google/uuid"
"github.com/stretchr/testify/require"
"github.com/pocket-id/pocket-id/backend/internal/appconfig"
@@ -54,7 +54,7 @@ func TestUpdateProfilePictureRejectsInvalidImageData(t *testing.T) {
userService, _ := newTestUserService(t)
config := &appconfig.AppConfigModel{RequireUserEmail: "false"}
user, err := userService.CreateUser(t.Context(), config, dto.UserCreateDto{
ID: uuid.NewString(),
ID: uuid.NewV4().String(),
Username: "image-test",
})
require.NoError(t, err)
@@ -70,7 +70,7 @@ func TestUpdateProfilePictureRejectsInvalidImageData(t *testing.T) {
func TestProfilePictureUpdatesRejectMissingUser(t *testing.T) {
userService, _ := newTestUserService(t)
missingUserID := uuid.NewString()
missingUserID := uuid.NewV4().String()
err := userService.UpdateProfilePicture(t.Context(), missingUserID, strings.NewReader("not an image"))
require.True(t, apperror.IsCode(err, apperror.CodeUserNotFound))

View File

@@ -9,8 +9,7 @@ import (
"os"
"path/filepath"
"strings"
"github.com/google/uuid"
"uuid"
)
type filesystemStorage struct {
@@ -51,7 +50,7 @@ func (s *filesystemStorage) Save(_ context.Context, path string, data io.Reader)
}
// Our strategy is to save to a separate file and then rename it to override the original file
tmpName := path + "." + uuid.NewString() + "-tmp"
tmpName := path + "." + uuid.NewV4().String() + "-tmp"
// Write to the temporary file
tmpFile, err := s.root.Create(tmpName)

View File

@@ -7,8 +7,8 @@ import (
"sort"
"strings"
"time"
"uuid"
"github.com/google/uuid"
"github.com/italypaleale/francis/actor"
"gorm.io/gorm"
@@ -347,7 +347,7 @@ func (s *Service) CreateSignupToken(ctx context.Context, ttl time.Duration, usag
now := time.Now().Round(time.Second)
state := SignupTokenState{
ID: uuid.NewString(),
ID: uuid.NewV4().String(),
ExpiresAt: now.Add(ttl),
UsageLimit: usageLimit,
UsageCount: 0,