Bump dependencies

- chroma/v2: v2.20.0 → v2.21.1
- go-pkgz/auth/v2: v2.1.0 → v2.1.1
- go-pkgz/rest: v1.20.4 → v1.20.6
- golang.org/x/* packages to latest

Also exclude "meaningless package names" revive warning in linter config.
This commit is contained in:
Umputun
2025-12-24 01:48:14 -06:00
parent d5b07d7670
commit 307e69e5c1
74 changed files with 2106 additions and 311 deletions
+4 -7
View File
@@ -172,8 +172,7 @@ func (s *Service) Handlers() (authHandler, avatarHandler http.Handler) {
// allow logout without specifying provider
if elems[len(elems)-1] == "logout" {
if len(s.providers) == 0 {
w.WriteHeader(http.StatusBadRequest)
rest.RenderJSON(w, rest.JSON{"error": "providers not defined"})
_ = rest.EncodeJSON(w, http.StatusBadRequest, rest.JSON{"error": "providers not defined"})
return
}
s.providers[0].Handler(w, r)
@@ -184,12 +183,11 @@ func (s *Service) Handlers() (authHandler, avatarHandler http.Handler) {
if elems[len(elems)-1] == "user" {
claims, _, err := s.jwtService.Get(r)
if err != nil || claims.User == nil {
w.WriteHeader(http.StatusUnauthorized)
msg := "user is nil"
if err != nil {
msg = err.Error()
}
rest.RenderJSON(w, rest.JSON{"error": msg})
_ = rest.EncodeJSON(w, http.StatusUnauthorized, rest.JSON{"error": msg})
return
}
rest.RenderJSON(w, claims.User)
@@ -211,8 +209,7 @@ func (s *Service) Handlers() (authHandler, avatarHandler http.Handler) {
provName := elems[len(elems)-2]
p, err := s.Provider(provName)
if err != nil {
w.WriteHeader(http.StatusBadRequest)
rest.RenderJSON(w, rest.JSON{"error": fmt.Sprintf("provider %s not supported", provName)})
_ = rest.EncodeJSON(w, http.StatusBadRequest, rest.JSON{"error": fmt.Sprintf("provider %s not supported", provName)})
return
}
p.Handler(w, r)
@@ -347,7 +344,7 @@ func (s *Service) AddAppleProvider(appleConfig provider.AppleConfig, privKeyLoad
L: s.logger,
}
// Error checking at create need for catch one when apple private key init
// error checking at create need for catch one when apple private key init
appleProvider, err := provider.NewApple(p, appleConfig, privKeyLoader)
if err != nil {
return fmt.Errorf("an AppleProvider creating failed: %w", err)
+1 -1
View File
@@ -194,7 +194,7 @@ func (p *Proxy) resize(reader io.Reader, limit int) io.Reader {
newW, newH = limit, h*limit/w
}
m := image.NewRGBA(image.Rect(0, 0, newW, newH))
// Slower than `draw.ApproxBiLinear.Scale()` but better quality.
// slower than `draw.ApproxBiLinear.Scale()` but better quality.
draw.BiLinear.Scale(m, m.Bounds(), src, src.Bounds(), draw.Src, nil)
var out bytes.Buffer
+1 -1
View File
@@ -189,7 +189,7 @@ func (a *Authenticator) refreshExpiredToken(w http.ResponseWriter, claims token.
}
claims.ExpiresAt = nil // this will cause now+duration for refreshed token
c, err := a.JWTService.Set(w, claims) // Set changes token
c, err := a.JWTService.Set(w, claims) // set changes token
if err != nil {
return token.Claims{}, err
}
+11 -11
View File
@@ -49,22 +49,22 @@ const (
// appleVerificationResponse is based on https://developer.apple.com/documentation/signinwithapplerestapi/tokenresponse
type appleVerificationResponse struct {
// A token used to access allowed user data, but now not implemented public interface for it.
// a token used to access allowed user data, but now not implemented public interface for it.
AccessToken string `json:"access_token"`
// Access token type, always equal the "bearer".
// access token type, always equal the "bearer".
TokenType string `json:"token_type"`
// Access token expires time in seconds. Always equal 3600 seconds (1 hour)
// access token expires time in seconds. Always equal 3600 seconds (1 hour)
ExpiresIn int `json:"expires_in"`
// The refresh token used to regenerate new access tokens.
// the refresh token used to regenerate new access tokens.
RefreshToken string `json:"refresh_token"`
// Main JSON Web Token that contains the user’s identity information.
// main JSON Web Token that contains the user’s identity information.
IDToken string `json:"id_token"`
// Used to capture any error returned in response. Always check error for empty
// used to capture any error returned in response. Always check error for empty
Error string `json:"error"`
}
@@ -443,7 +443,7 @@ func (ah *AppleHandler) exchange(ctx context.Context, code, redirectURI string,
return err
}
// Trying to decode (unmarshal json) data of response
// trying to decode (unmarshal json) data of response
err = json.NewDecoder(res.Body).Decode(result)
if err != nil {
return fmt.Errorf("unmarshalling data from apple service response failed: %w", err)
@@ -455,8 +455,8 @@ func (ah *AppleHandler) exchange(ctx context.Context, code, redirectURI string,
}
}()
// If above operation done successfully checking a response code and error descriptions, if one exist.
// Apple service will response either 200 (OK) or 400 (any error).
// if above operation done successfully checking a response code and error descriptions, if one exist.
// apple service will response either 200 (OK) or 400 (any error).
if res.StatusCode != http.StatusOK || result.Error != "" {
return fmt.Errorf("apple token service error: %s", result.Error)
}
@@ -471,7 +471,7 @@ func (ah *AppleHandler) createClientSecret() (string, error) {
if ah.conf.privateKey == nil {
return "", fmt.Errorf("private key can't be empty")
}
// Create a claims
// create a claims
now := time.Now()
exp := now.Add(time.Minute * 30) // default value
@@ -502,7 +502,7 @@ func (ah *AppleHandler) parseUserData(user *token.User, jUser string) {
var userData UserData
// Catch error for log only. No need break flow if user name doesn't exist
// catch error for log only. No need break flow if user name doesn't exist
if err := json.Unmarshal([]byte(jUser), &userData); err != nil {
ah.Logf("[DEBUG] failed to parse user data %s: %v", user, err)
user.Name = "noname_" + user.ID[6:12] // paste noname if user name failed to parse
+6 -6
View File
@@ -20,14 +20,14 @@ type Email struct {
type EmailParams struct {
Host string // SMTP host
Port int // SMTP port
From string // From email field
Subject string // Email subject
ContentType string // Content type
From string // from email field
Subject string // email subject
ContentType string // content type
TLS bool // TLS auth
StartTLS bool // StartTLS auth
InsecureSkipVerify bool // Skip certificate verification
Charset string // Character set
StartTLS bool // startTLS auth
InsecureSkipVerify bool // skip certificate verification
Charset string // character set
LoginAuth bool // LOGIN auth method instead of default PLAIN, needed for Office 365 and outlook.com
SMTPUserName string // username
SMTPPassword string // password
+11 -11
View File
@@ -15,7 +15,7 @@ import (
"sync/atomic"
"time"
"github.com/go-pkgz/repeater"
"github.com/go-pkgz/repeater/v2"
"github.com/go-pkgz/rest"
"github.com/golang-jwt/jwt/v5"
@@ -63,7 +63,7 @@ var expiredCleanupInterval = time.Minute * 5 // interval to check and clean up e
// Run starts processing login requests sent in Telegram
// Blocks caller
func (th *TelegramHandler) Run(ctx context.Context) error {
// Initialization
// initialization
atomic.AddInt32(&th.run, 1)
info, err := th.Telegram.BotInfo(ctx)
if err != nil {
@@ -168,7 +168,7 @@ func (th *TelegramHandler) processUpdates(ctx context.Context, updates *telegram
th.requests.RLock()
authRequest, ok := th.requests.data[token]
if !ok { // No such token
if !ok { // no such token
th.requests.RUnlock()
err := th.Telegram.Send(ctx, update.Message.Chat.ID, th.ErrorMsg)
if err != nil {
@@ -256,7 +256,7 @@ func (th *TelegramHandler) LoginHandler(w http.ResponseWriter, r *http.Request)
queryToken := r.URL.Query().Get("token")
if queryToken == "" {
// GET /login (No token supplied)
// Generate and send token
// generate and send token
token, err := randToken()
if err != nil {
rest.SendErrorJSON(w, r, th.L, http.StatusInternalServerError, err, "failed to generate code")
@@ -322,7 +322,7 @@ func (th *TelegramHandler) LoginHandler(w http.ResponseWriter, r *http.Request)
rest.RenderJSON(w, claims.User)
// Delete request
// delete request
th.requests.Lock()
defer th.requests.Unlock()
delete(th.requests.data, queryToken)
@@ -342,8 +342,8 @@ type tgAPI struct {
token string
client *http.Client
// Identifier of the first update to be requested.
// Should be equal to LastSeenUpdateID + 1
// identifier of the first update to be requested.
// should be equal to LastSeenUpdateID + 1
// See https://core.telegram.org/bots/api#getupdates
updateOffset int
}
@@ -387,7 +387,7 @@ func (tg *tgAPI) Send(ctx context.Context, id int, msg string) error {
// Avatar returns URL to user avatar
func (tg *tgAPI) Avatar(ctx context.Context, id int) (string, error) {
// Get profile pictures
// get profile pictures
url := fmt.Sprintf(`getUserProfilePhotos?user_id=%d`, id)
var profilePhotos = struct {
@@ -402,12 +402,12 @@ func (tg *tgAPI) Avatar(ctx context.Context, id int) (string, error) {
return "", err
}
// User does not have profile picture set or it is hidden in privacy settings
// user does not have profile picture set or it is hidden in privacy settings
if len(profilePhotos.Result.Photos) == 0 || len(profilePhotos.Result.Photos[0]) == 0 {
return "", nil
}
// Get max possible picture size
// get max possible picture size
last := len(profilePhotos.Result.Photos[0]) - 1
fileID := profilePhotos.Result.Photos[0][last].ID
url = fmt.Sprintf(`getFile?file_id=%s`, fileID)
@@ -450,7 +450,7 @@ func (tg *tgAPI) BotInfo(ctx context.Context) (*botInfo, error) {
}
func (tg *tgAPI) request(ctx context.Context, method string, data interface{}) error {
return repeater.NewDefault(3, time.Millisecond*50).Do(ctx, func() error {
return repeater.NewFixed(3, time.Millisecond*50).Do(ctx, func() error {
url := fmt.Sprintf("https://api.telegram.org/bot%s/%s", tg.token, method)
req, err := http.NewRequestWithContext(ctx, "GET", url, http.NoBody)
+3 -2
View File
@@ -231,7 +231,7 @@ func (j *Service) validate(claims *Claims) error {
return nil
}
// Ignore "ErrTokenExpired" if it is the only error.
// ignore "ErrTokenExpired" if it is the only error.
if errors.Is(err, jwt.ErrTokenExpired) {
if uw, ok := err.(interface{ Unwrap() []error }); ok && len(uw.Unwrap()) == 1 {
return nil
@@ -266,7 +266,8 @@ func (j *Service) Set(w http.ResponseWriter, claims Claims) (Claims, error) {
if j.SendJWTHeader {
w.Header().Set(j.JWTHeaderKey, tokenString)
return claims, nil
// don't return here - fall through to also set cookies
// cookies are needed for OAuth redirect flows where headers don't survive redirects
}
cookieExpiration := 0 // session cookie