initial commit

This commit is contained in:
m.zare
2026-04-10 18:25:21 +03:30
commit 77ca6c34a3
263 changed files with 34470 additions and 0 deletions

121
pkg/jwt/token_generator.go Normal file
View File

@@ -0,0 +1,121 @@
package jwt
import (
"context"
"errors"
"time"
"github.com/lestrrat-go/jwx/v3/jwa"
"github.com/lestrrat-go/jwx/v3/jwt"
)
var (
ErrTokenVerificationFailed = errors.New("token verification failed")
)
type tokenService struct {
secretKey []byte
accessTokenExpiration time.Duration
refreshTokenExpiration time.Duration
}
func New(secret string, ate, rfe time.Duration) TokenService {
secretKey := []byte(secret)
return &tokenService{
secretKey: secretKey,
accessTokenExpiration: ate,
refreshTokenExpiration: rfe,
}
}
func (ts tokenService) GenerateAccessRefreshTokenPair(
ctx context.Context,
tokenData *TokenData,
) (*AccessRefreshTokenPair, error) {
accessTokenExp := time.Now().Add(ts.accessTokenExpiration)
generateAccessJwt, err := ts.generateJwt(accessTokenExp, tokenData.Sub, "alinme-web")
if err != nil {
return nil, err
}
refreshTokenExp := time.Now().Add(ts.refreshTokenExpiration)
generateRefreshJwt, err := ts.generateJwt(refreshTokenExp, tokenData.Sub, "alinme-web")
if err != nil {
return nil, err
}
return &AccessRefreshTokenPair{
AccessToken: generateAccessJwt,
AccessTokenExpiresAt: accessTokenExp,
RefreshToken: generateRefreshJwt,
RefreshTokenExpiresAt: refreshTokenExp,
}, nil
}
func (ts tokenService) generateJwt(exp time.Time, sub string, aud string) (string, error) {
t, err := jwt.NewBuilder().
Subject(sub).
IssuedAt(time.Now()).
Issuer("alinme-server").
Audience([]string{aud}).
Expiration(exp).
Build()
if err != nil {
return "", err
}
signed, err := jwt.Sign(t, jwt.WithKey(jwa.HS256(), ts.secretKey))
if err != nil {
return "", err
}
return string(signed), nil
}
func (ts tokenService) VerifyToken(ctx context.Context, accessToken string) (*TokenPayload, error) {
parsed, err := jwt.Parse([]byte(accessToken), jwt.WithKey(jwa.HS256(), ts.secretKey))
if err != nil {
return nil, ErrTokenVerificationFailed
}
sub, ok := parsed.Subject()
if !ok {
return nil, ErrTokenVerificationFailed
}
aud, ok := parsed.Audience()
if !ok {
return nil, ErrTokenVerificationFailed
}
iat, ok := parsed.IssuedAt()
if !ok {
return nil, ErrTokenVerificationFailed
}
exp, ok := parsed.Expiration()
if !ok {
return nil, ErrTokenVerificationFailed
}
iss, ok := parsed.Issuer()
if !ok {
return nil, ErrTokenVerificationFailed
}
return &TokenPayload{
Sub: sub,
Aud: aud,
Iat: iat,
Exp: exp,
Iss: iss,
}, nil
}
func (ts tokenService) GenerateToken(ctx context.Context, input *GenerateTokenInput) (string, error) {
generateJwt, err := ts.generateJwt(time.Now().Add(time.Minute*5), input.Sub, input.Aud)
if err != nil {
return "", err
}
return generateJwt, nil
}