//go:build ignore package security import ( "fmt" "time" "backupx/server/internal/model" "github.com/golang-jwt/jwt/v5" ) type Claims struct { UserID uint `json:"userId"` Username string `json:"username"` Role string `json:"role"` jwt.RegisteredClaims } type JWTManager struct { secret []byte duration time.Duration } func NewJWTManager(secret string, duration time.Duration) *JWTManager { return &JWTManager{secret: []byte(secret), duration: duration} } func (m *JWTManager) IssueToken(user *model.User) (string, error) { now := time.Now().UTC() claims := Claims{ UserID: user.ID, Username: user.Username, Role: user.Role, RegisteredClaims: jwt.RegisteredClaims{ Subject: fmt.Sprintf("%d", user.ID), IssuedAt: jwt.NewNumericDate(now), ExpiresAt: jwt.NewNumericDate(now.Add(m.duration)), }, } token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims) return token.SignedString(m.secret) } func (m *JWTManager) Parse(tokenValue string) (*Claims, error) { token, err := jwt.ParseWithClaims(tokenValue, &Claims{}, func(token *jwt.Token) (any, error) { if token.Method != jwt.SigningMethodHS256 { return nil, fmt.Errorf("unexpected signing method") } return m.secret, nil }) if err != nil { return nil, err } claims, ok := token.Claims.(*Claims) if !ok || !token.Valid { return nil, fmt.Errorf("invalid token") } return claims, nil }