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