package utils import ( "errors" "fmt" models "kemendagri/sipd/services/sipd_auth/model" "os" "strconv" "time" "github.com/golang-jwt/jwt/v4" "github.com/jackc/pgx/v5/pgxpool" ) type MyCustomClaim struct { jwt.RegisteredClaims Tahun int `json:"tahun"` IdUser int64 `json:"id_user"` IdDaerah int64 `json:"id_daerah"` KodeProvinsi string `json:"kode_provinsi"` KodeDdn string `json:"kode_ddn"` IdSkpd int64 `json:"id_skpd"` IdRole int `json:"id_role"` IdPegawai int64 `json:"id_pegawai"` SubDomainDaerah string `json:"sub_domain_daerah" xml:"sub_domain_daerah"` } type JWTManager struct { secretKey string issuer string } func NewJWTManager(secretKey, iss string) *JWTManager { return &JWTManager{secretKey, iss} } func (m *JWTManager) Generate(dbConn *pgxpool.Pool, user models.User, tahun int, idPeg int64) (token, refreshToken string, jwtExpDuration time.Duration, err error) { // ambil data durasi expired jwt dan refresh_token dari table sys config var jwtExpiredMinutes, refreshTokenExpiredHour int64 jwtExpiredMinutes, err = strconv.ParseInt(os.Getenv("JWT_EXPIRED_MINUTES"), 10, 64) refreshTokenExpiredHour, err = strconv.ParseInt(os.Getenv("REFRESH_TOKEN_EXPIRED_HOUR"), 10, 64) jwtSub := fmt.Sprintf("%d.%d", user.IdUser, user.IdDaerah) jwtExpDuration = time.Duration(jwtExpiredMinutes) * time.Minute // Create jwt token jwtClaims := MyCustomClaim{ RegisteredClaims: jwt.RegisteredClaims{ Issuer: m.issuer, Subject: jwtSub, ExpiresAt: jwt.NewNumericDate(time.Now().Add(jwtExpDuration)), IssuedAt: &jwt.NumericDate{Time: time.Now()}, }, Tahun: tahun, IdUser: user.IdUser, IdDaerah: user.IdDaerah, KodeProvinsi: user.KodeProvinsi, KodeDdn: user.KodeDdn, IdSkpd: user.IdSkpd, IdRole: user.IdRole, IdPegawai: idPeg, SubDomainDaerah: user.SubDomainDaerah, } token, err = jwt.NewWithClaims(jwt.SigningMethodHS256, jwtClaims).SignedString([]byte(m.secretKey)) if err != nil { return } // Create refresh token refreshTokenClaims := MyCustomClaim{ RegisteredClaims: jwt.RegisteredClaims{ Issuer: m.issuer, Subject: jwtSub, ExpiresAt: jwt.NewNumericDate(time.Now().Add(time.Hour * time.Duration(refreshTokenExpiredHour))), IssuedAt: &jwt.NumericDate{Time: time.Now()}, }, Tahun: tahun, IdUser: user.IdUser, IdDaerah: user.IdDaerah, KodeProvinsi: user.KodeProvinsi, KodeDdn: user.KodeDdn, IdSkpd: user.IdSkpd, IdRole: user.IdRole, IdPegawai: idPeg, SubDomainDaerah: user.SubDomainDaerah, } /*refreshTokenClaims := jwt.RegisteredClaims{ Issuer: m.issuer, Subject: jwtSub, ExpiresAt: jwt.NewNumericDate(time.Now().Add(time.Hour * time.Duration(refreshTokenExpiredHour))), IssuedAt: &jwt.NumericDate{Time: time.Now()}, }*/ refreshToken, err = jwt.NewWithClaims(jwt.SigningMethodHS256, refreshTokenClaims).SignedString([]byte(m.secretKey)) if err != nil { return } return } func (m *JWTManager) Verify(token string) (*MyCustomClaim, error) { var r *MyCustomClaim tDecoded, err := jwt.ParseWithClaims(token, &MyCustomClaim{}, func(token *jwt.Token) (interface{}, error) { return []byte(m.secretKey), nil }) if err != nil { return r, err } if claims, ok := tDecoded.Claims.(*MyCustomClaim); ok && tDecoded.Valid { if claims.ExpiresAt.Unix() < time.Now().Unix() { return r, errors.New("token expired") } return claims, nil } return r, errors.New("invalid token") }