errors.go raw

   1  package jwt
   2  
   3  import (
   4  	"errors"
   5  	"fmt"
   6  	"strings"
   7  )
   8  
   9  var (
  10  	ErrInvalidKey                = errors.New("key is invalid")
  11  	ErrInvalidKeyType            = errors.New("key is of invalid type")
  12  	ErrHashUnavailable           = errors.New("the requested hash function is unavailable")
  13  	ErrTokenMalformed            = errors.New("token is malformed")
  14  	ErrTokenUnverifiable         = errors.New("token is unverifiable")
  15  	ErrTokenSignatureInvalid     = errors.New("token signature is invalid")
  16  	ErrTokenRequiredClaimMissing = errors.New("token is missing required claim")
  17  	ErrTokenInvalidAudience      = errors.New("token has invalid audience")
  18  	ErrTokenExpired              = errors.New("token is expired")
  19  	ErrTokenUsedBeforeIssued     = errors.New("token used before issued")
  20  	ErrTokenInvalidIssuer        = errors.New("token has invalid issuer")
  21  	ErrTokenInvalidSubject       = errors.New("token has invalid subject")
  22  	ErrTokenNotValidYet          = errors.New("token is not valid yet")
  23  	ErrTokenInvalidId            = errors.New("token has invalid id")
  24  	ErrTokenInvalidClaims        = errors.New("token has invalid claims")
  25  	ErrInvalidType               = errors.New("invalid type for claim")
  26  )
  27  
  28  // joinedError is an error type that works similar to what [errors.Join]
  29  // produces, with the exception that it has a nice error string; mainly its
  30  // error messages are concatenated using a comma, rather than a newline.
  31  type joinedError struct {
  32  	errs []error
  33  }
  34  
  35  func (je joinedError) Error() string {
  36  	msg := []string{}
  37  	for _, err := range je.errs {
  38  		msg = append(msg, err.Error())
  39  	}
  40  
  41  	return strings.Join(msg, ", ")
  42  }
  43  
  44  // joinErrors joins together multiple errors. Useful for scenarios where
  45  // multiple errors next to each other occur, e.g., in claims validation.
  46  func joinErrors(errs ...error) error {
  47  	return &joinedError{
  48  		errs: errs,
  49  	}
  50  }
  51  
  52  // Unwrap implements the multiple error unwrapping for this error type, which is
  53  // possible in Go 1.20.
  54  func (je joinedError) Unwrap() []error {
  55  	return je.errs
  56  }
  57  
  58  // newError creates a new error message with a detailed error message. The
  59  // message will be prefixed with the contents of the supplied error type.
  60  // Additionally, more errors, that provide more context can be supplied which
  61  // will be appended to the message. This makes use of Go 1.20's possibility to
  62  // include more than one %w formatting directive in [fmt.Errorf].
  63  //
  64  // For example,
  65  //
  66  //	newError("no keyfunc was provided", ErrTokenUnverifiable)
  67  //
  68  // will produce the error string
  69  //
  70  //	"token is unverifiable: no keyfunc was provided"
  71  func newError(message string, err error, more ...error) error {
  72  	var format string
  73  	var args []any
  74  	if message != "" {
  75  		format = "%w: %s"
  76  		args = []any{err, message}
  77  	} else {
  78  		format = "%w"
  79  		args = []any{err}
  80  	}
  81  
  82  	for _, e := range more {
  83  		format += ": %w"
  84  		args = append(args, e)
  85  	}
  86  
  87  	err = fmt.Errorf(format, args...)
  88  	return err
  89  }
  90