124 lines
3.5 KiB
Go
124 lines
3.5 KiB
Go
package jwtutil
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
"time"
|
|
|
|
"github.com/SamuelTariku/FortuneBet-Backend/internal/domain"
|
|
"github.com/golang-jwt/jwt/v5"
|
|
)
|
|
|
|
var (
|
|
ErrExpiredToken = errors.New("token expired")
|
|
ErrMalformedToken = errors.New("token malformed")
|
|
ErrTokenNotExpired = errors.New("token not expired")
|
|
ErrRefreshTokenNotFound = errors.New("refresh token not found")
|
|
)
|
|
|
|
|
|
type UserClaim struct {
|
|
jwt.RegisteredClaims
|
|
UserId int64
|
|
Role domain.Role
|
|
CompanyID domain.NullJwtInt64
|
|
}
|
|
|
|
type PopOKClaim struct {
|
|
jwt.RegisteredClaims
|
|
UserID int64 `json:"user_id"`
|
|
Username string `json:"username"`
|
|
Currency string `json:"currency"`
|
|
Lang string `json:"lang"`
|
|
Mode string `json:"mode"`
|
|
SessionID string `json:"session_id"`
|
|
CompanyID domain.NullJwtInt64 `json:"company_id"`
|
|
}
|
|
|
|
type JwtConfig struct {
|
|
JwtAccessKey string
|
|
JwtAccessExpiry int
|
|
}
|
|
|
|
func CreateJwt(userId int64, Role domain.Role, CompanyID domain.ValidInt64, key string, expiry int) (string, error) {
|
|
token := jwt.NewWithClaims(jwt.SigningMethodHS256, UserClaim{
|
|
RegisteredClaims: jwt.RegisteredClaims{
|
|
Issuer: "fortune-bet",
|
|
IssuedAt: jwt.NewNumericDate(time.Now()),
|
|
Audience: jwt.ClaimStrings{"api.fortunebets.net"},
|
|
NotBefore: jwt.NewNumericDate(time.Now()),
|
|
ExpiresAt: jwt.NewNumericDate(time.Now().Add(time.Duration(expiry) * time.Second)),
|
|
},
|
|
UserId: userId,
|
|
Role: Role,
|
|
CompanyID: domain.NullJwtInt64{
|
|
Value: CompanyID.Value,
|
|
Valid: CompanyID.Valid,
|
|
},
|
|
})
|
|
jwtToken, err := token.SignedString([]byte(key))
|
|
return jwtToken, err
|
|
}
|
|
|
|
func CreatePopOKJwt(userID int64, CompanyID domain.ValidInt64, username, currency, lang, mode, sessionID, key string, expiry time.Duration) (string, error) {
|
|
token := jwt.NewWithClaims(jwt.SigningMethodHS256, PopOKClaim{
|
|
RegisteredClaims: jwt.RegisteredClaims{
|
|
Issuer: "fortune-bet",
|
|
Audience: jwt.ClaimStrings{"popokgaming.com"},
|
|
IssuedAt: jwt.NewNumericDate(time.Now()),
|
|
NotBefore: jwt.NewNumericDate(time.Now()),
|
|
ExpiresAt: jwt.NewNumericDate(time.Now().Add(expiry)),
|
|
},
|
|
UserID: userID,
|
|
Username: username, // ✅ Must be a valid string
|
|
Currency: currency,
|
|
Lang: lang,
|
|
Mode: mode,
|
|
SessionID: sessionID,
|
|
CompanyID: domain.NullJwtInt64{
|
|
Value: CompanyID.Value,
|
|
Valid: CompanyID.Valid,
|
|
},
|
|
})
|
|
return token.SignedString([]byte(key))
|
|
}
|
|
|
|
func ParseJwt(jwtToken string, key string) (*UserClaim, error) {
|
|
token, err := jwt.ParseWithClaims(jwtToken, &UserClaim{}, func(token *jwt.Token) (interface{}, error) {
|
|
return []byte(key), nil
|
|
})
|
|
if err != nil {
|
|
if errors.Is(err, jwt.ErrTokenExpired) {
|
|
return nil, ErrExpiredToken
|
|
}
|
|
if errors.Is(err, jwt.ErrTokenMalformed) {
|
|
fmt.Printf("error %v", err.Error())
|
|
return nil, ErrMalformedToken
|
|
}
|
|
return nil, err
|
|
}
|
|
if claims, ok := token.Claims.(*UserClaim); ok && token.Valid {
|
|
return claims, nil
|
|
}
|
|
return nil, errors.New("invalid token claims")
|
|
}
|
|
|
|
func ParsePopOKJwt(jwtToken string, key string) (*PopOKClaim, error) {
|
|
token, err := jwt.ParseWithClaims(jwtToken, &PopOKClaim{}, func(token *jwt.Token) (interface{}, error) {
|
|
return []byte(key), nil
|
|
})
|
|
if err != nil {
|
|
if errors.Is(err, jwt.ErrTokenExpired) {
|
|
return nil, ErrExpiredToken
|
|
}
|
|
if errors.Is(err, jwt.ErrTokenMalformed) {
|
|
return nil, ErrMalformedToken
|
|
}
|
|
return nil, err
|
|
}
|
|
if claims, ok := token.Claims.(*PopOKClaim); ok && token.Valid {
|
|
return claims, nil
|
|
}
|
|
return nil, errors.New("invalid PopOK token claims")
|
|
}
|