package middlewares import ( "context" "net/http" "time" "gitea.konchin.com/go2025/backend/models" "gitea.konchin.com/go2025/backend/types" "github.com/golang-jwt/jwt/v5" "github.com/spf13/viper" "github.com/uptrace/bunrouter" ) func (self *Handlers) CheckRefreshToken( next bunrouter.HandlerFunc, ) bunrouter.HandlerFunc { return func(w http.ResponseWriter, req bunrouter.Request) error { ctx := req.Context() refreshTokenCookie, err := req.Cookie("refresh_token") if err != nil { return HTTPError{ StatusCode: http.StatusUnauthorized, Message: "user did not login", OriginError: err, } } var claim models.RefreshTokenClaim token, err := jwt.ParseWithClaims(refreshTokenCookie.Value, &claim, func(*jwt.Token) (interface{}, error) { return []byte(viper.GetString("refresh-token-secret")), nil }) if err != nil { return HTTPError{ StatusCode: http.StatusUnauthorized, Message: "refresh token jwt cannot parse", OriginError: err, } } if !token.Valid { return HTTPError{ StatusCode: http.StatusUnauthorized, Message: "refresh token jwt invalid", } } // check time and refresh timeLeft := claim.ExpiresAt.Time.Sub(time.Now()) / time.Second if int64(timeLeft) < viper.GetInt64("refresh-token-timeout")/2 { session, err := self.db.UpdateRefreshToken(ctx, claim.UserId) if err != nil { return HTTPError{ StatusCode: http.StatusInternalServerError, Message: "upsert session failed", OriginError: err, } } http.SetCookie(w, &http.Cookie{ Name: "refresh_token", Value: session.RefreshToken, Path: "/", Secure: false, HttpOnly: true, SameSite: http.SameSiteLaxMode, }) } ctx = context.WithValue(ctx, types.RefreshToken(""), claim) return next(w, req.WithContext(ctx)) } }