Passport/pkg/internal/services/jwt.go

92 lines
2.1 KiB
Go
Raw Normal View History

2024-04-20 11:04:33 +00:00
package services
2024-01-06 17:56:32 +00:00
import (
"fmt"
"time"
2024-07-28 12:04:22 +00:00
"git.solsynth.dev/hydrogen/passport/pkg/internal/models"
2024-01-06 17:56:32 +00:00
"github.com/golang-jwt/jwt/v5"
"github.com/spf13/viper"
)
type PayloadClaims struct {
jwt.RegisteredClaims
2024-07-28 12:04:22 +00:00
// 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
2024-07-28 11:50:49 +00:00
AuthorizedParties string `json:"azp,omitempty"`
2024-07-28 14:30:51 +00:00
Nonce string `json:"nonce,omitempty"`
2024-07-28 11:50:49 +00:00
Type string `json:"typ"`
2024-01-06 17:56:32 +00:00
}
const (
JwtAccessType = "access"
JwtRefreshType = "refresh"
)
2024-07-28 14:30:51 +00:00
func EncodeJwt(id string, typ, sub, sed string, nonce *string, aud []string, exp time.Time, idTokenUser ...models.Account) (string, error) {
2024-07-28 11:50:49 +00:00
var azp string
for _, item := range aud {
if item != InternalTokenAudience {
azp = item
break
}
}
2024-07-28 12:04:22 +00:00
claims := PayloadClaims{
2024-07-28 11:50:49 +00:00
RegisteredClaims: jwt.RegisteredClaims{
2024-01-06 17:56:32 +00:00
Subject: sub,
Audience: aud,
Issuer: viper.GetString("security.issuer"),
2024-01-06 17:56:32 +00:00
ExpiresAt: jwt.NewNumericDate(exp),
NotBefore: jwt.NewNumericDate(time.Now()),
IssuedAt: jwt.NewNumericDate(time.Now()),
ID: id,
},
2024-07-28 11:50:49 +00:00
AuthorizedParties: azp,
SessionID: sed,
Type: typ,
2024-07-28 12:04:22 +00:00
}
if len(idTokenUser) > 0 {
user := idTokenUser[0]
claims.Name = user.Name
claims.Nick = user.Nick
claims.Email = user.GetPrimaryEmail().Content
}
2024-07-28 14:30:51 +00:00
if nonce != nil {
claims.Nonce = *nonce
}
2024-07-28 12:04:22 +00:00
tk := jwt.NewWithClaims(jwt.SigningMethodHS512, claims)
2024-01-06 17:56:32 +00:00
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")
}
}