2fas-server/internal/pass/sign/verify.go
2024-01-24 20:57:31 +01:00

53 lines
1.3 KiB
Go

package sign
import (
"errors"
"fmt"
"slices"
"github.com/golang-jwt/jwt/v5"
)
var ErrInvalidClaims = errors.New("invalid claims")
type customClaims struct {
ConnectionID string `json:"c_id"`
jwt.RegisteredClaims
}
// CanI establish connection with type tp given claims in token.
// Returns extension_id from claims if token is valid for given type.
func (s Service) CanI(tokenString string, ct ConnectionType) (string, error) {
cl := customClaims{}
// In Sign we removed `jwtHeader` from JWT before returning it.
// We need to add it again before doing the verification.
tokenString = jwtHeader + tokenString
token, err := jwt.ParseWithClaims(
tokenString,
&cl,
func(token *jwt.Token) (interface{}, error) {
return s.publicKey, nil
},
jwt.WithValidMethods([]string{"ES256"}),
jwt.WithExpirationRequired(),
)
if err != nil {
return "", fmt.Errorf("failed to parse token: %w", err)
}
audClaims, err := token.Claims.GetAudience()
if err != nil {
return "", fmt.Errorf("failed to get claims: %w", err)
}
if !slices.Contains(audClaims, string(ct)) {
return "", fmt.Errorf("%w: claim %q not found in claims", ErrInvalidClaims, ct)
}
if cl.ConnectionID == "" {
return "", fmt.Errorf("%w: claim %q not found in claims", ErrInvalidClaims, "c_id")
}
// TODO: rename connectionID to extensionID.
return cl.ConnectionID, nil
}