diff --git a/auth/auth.go b/auth/auth.go index 14ad28c7..ce908f62 100644 --- a/auth/auth.go +++ b/auth/auth.go @@ -24,6 +24,9 @@ type TokenInfo struct { // The error that a TokenVerifier should return if the token cannot be verified. var ErrInvalidToken = errors.New("invalid token") +// The error that a TokenVerifier should return for OAuth-specific protocol errors. +var ErrOAuth = errors.New("oauth error") + // A TokenVerifier checks the validity of a bearer token, and extracts information // from it. If verification fails, it should return an error that unwraps to ErrInvalidToken. type TokenVerifier func(ctx context.Context, token string) (*TokenInfo, error) @@ -88,7 +91,9 @@ func verify(ctx context.Context, verifier TokenVerifier, opts *RequireBearerToke if errors.Is(err, ErrInvalidToken) { return nil, err.Error(), http.StatusUnauthorized } - // TODO: the TS SDK distinguishes another error, OAuthError, and returns a 400. + if errors.Is(err, ErrOAuth) { + return nil, err.Error(), http.StatusBadRequest + } // Investigate how that works. // See typescript-sdk/src/server/auth/middleware/bearerAuth.ts. return nil, err.Error(), http.StatusInternalServerError diff --git a/auth/auth_test.go b/auth/auth_test.go index 715b9bba..8da41ec6 100644 --- a/auth/auth_test.go +++ b/auth/auth_test.go @@ -19,6 +19,8 @@ func TestVerify(t *testing.T) { return &TokenInfo{Expiration: time.Now().Add(time.Hour)}, nil case "invalid": return nil, ErrInvalidToken + case "oauth": + return nil, ErrOAuth case "noexp": return &TokenInfo{}, nil case "expired": @@ -47,6 +49,10 @@ func TestVerify(t *testing.T) { "invalid", nil, "bearer invalid", "invalid token", 401, }, + { + "oauth error", nil, "Bearer oauth", + "oauth error", 400, + }, { "no expiration", nil, "Bearer noexp", "token missing expiration", 401,