package services import ( "fmt" "time" "git.solsynth.dev/hydrogen/passport/pkg/internal/models" "github.com/golang-jwt/jwt/v5" "github.com/spf13/viper" ) type PayloadClaims struct { jwt.RegisteredClaims // Internal Stuff SessionID string `json:"sed"` // ID Token Stuff Name string `json:"name,omitempty"` Nick string `json:"preferred_username,omitempty"` Email string `json:"email,omitempty"` // Additional Stuff AuthorizedParties string `json:"azp,omitempty"` Nonce string `json:"nonce,omitempty"` Type string `json:"typ"` } const ( JwtAccessType = "access" JwtRefreshType = "refresh" ) func EncodeJwt(id string, typ, sub, sed string, nonce *string, aud []string, exp time.Time, idTokenUser ...models.Account) (string, error) { var azp string for _, item := range aud { if item != InternalTokenAudience { azp = item break } } claims := PayloadClaims{ RegisteredClaims: jwt.RegisteredClaims{ Subject: sub, Audience: aud, Issuer: viper.GetString("security.issuer"), ExpiresAt: jwt.NewNumericDate(exp), NotBefore: jwt.NewNumericDate(time.Now()), IssuedAt: jwt.NewNumericDate(time.Now()), ID: id, }, AuthorizedParties: azp, SessionID: sed, Type: typ, } if len(idTokenUser) > 0 { user := idTokenUser[0] claims.Name = user.Name claims.Nick = user.Nick claims.Email = user.GetPrimaryEmail().Content } if nonce != nil { claims.Nonce = *nonce } tk := jwt.NewWithClaims(jwt.SigningMethodHS512, claims) return tk.SignedString([]byte(viper.GetString("secret"))) } func DecodeJwt(str string) (PayloadClaims, error) { var claims PayloadClaims tk, err := jwt.ParseWithClaims(str, &claims, func(token *jwt.Token) (interface{}, error) { if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok { return nil, fmt.Errorf("unexpected signing method: %v", token.Header["alg"]) } return []byte(viper.GetString("secret")), nil }) if err != nil { return claims, err } if data, ok := tk.Claims.(*PayloadClaims); ok { return *data, nil } else { return claims, fmt.Errorf("unexpected token payload: not payload claims type") } }