diff --git a/auth/api/auth/v1/client/types.go b/auth/api/auth/v1/client/types.go index 3354282eac..fdccb9ca60 100644 --- a/auth/api/auth/v1/client/types.go +++ b/auth/api/auth/v1/client/types.go @@ -34,3 +34,6 @@ type VerifiablePresentation = vc.VerifiablePresentation // AccessTokenResponse is an alias to use from within the API type AccessTokenResponse = oauth.TokenResponse + +// AccessTokenRequestFailedResponse is an alias to use from within the API +type AccessTokenRequestFailedResponse = oauth.ErrorResponse diff --git a/auth/api/iam/types.go b/auth/api/iam/types.go index edb59ae296..a5f73c64f5 100644 --- a/auth/api/iam/types.go +++ b/auth/api/iam/types.go @@ -20,6 +20,7 @@ package iam import ( "github.com/nuts-foundation/go-did/did" + "github.com/nuts-foundation/nuts-node/auth/oauth" "github.com/nuts-foundation/nuts-node/vcr/pe" "github.com/nuts-foundation/nuts-node/vdr/resolver" ) @@ -33,6 +34,9 @@ type DIDDocumentMetadata = resolver.DocumentMetadata // PresentationDefinition is an alias type PresentationDefinition = pe.PresentationDefinition +// TokenResponse is an alias +type TokenResponse = oauth.TokenResponse + const ( // responseTypeParam is the name of the response_type parameter. // Specified by https://datatracker.ietf.org/doc/html/rfc6749#section-3.1.1 diff --git a/auth/client/iam/client.go b/auth/client/iam/client.go index e367719da6..4a6f13297a 100644 --- a/auth/client/iam/client.go +++ b/auth/client/iam/client.go @@ -40,7 +40,7 @@ import ( // HTTPClient holds the server address and other basic settings for the http client type HTTPClient struct { strictMode bool - httpClient *core.StrictHTTPClient + httpClient core.HTTPRequestDoer } // NewHTTPClient creates a new api client. diff --git a/auth/client/iam/client_test.go b/auth/client/iam/client_test.go index b755c109c2..cc704fd82c 100644 --- a/auth/client/iam/client_test.go +++ b/auth/client/iam/client_test.go @@ -20,20 +20,17 @@ package iam import ( "context" - "github.com/nuts-foundation/nuts-node/core" + "github.com/nuts-foundation/go-did/did" + "github.com/nuts-foundation/nuts-node/auth/oauth" + http2 "github.com/nuts-foundation/nuts-node/test/http" "github.com/nuts-foundation/nuts-node/vcr/pe" "github.com/nuts-foundation/nuts-node/vdr/didweb" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" "net/http" "net/http/httptest" "net/url" "testing" - "time" - - "github.com/nuts-foundation/go-did/did" - "github.com/nuts-foundation/nuts-node/auth/oauth" - http2 "github.com/nuts-foundation/nuts-node/test/http" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" ) func TestHTTPClient_OAuthAuthorizationServerMetadata(t *testing.T) { @@ -185,6 +182,6 @@ func TestHTTPClient_PresentationDefinition(t *testing.T) { func testServerAndClient(t *testing.T, handler http.Handler) (*httptest.Server, *HTTPClient) { tlsServer := http2.TestTLSServer(t, handler) return tlsServer, &HTTPClient{ - httpClient: core.NewStrictHTTPClient(false, time.Second, tlsServer.TLS), + httpClient: tlsServer.Client(), } } diff --git a/auth/services/oauth/relying_party.go b/auth/services/oauth/relying_party.go index fce57cf3dd..5b3d01be91 100644 --- a/auth/services/oauth/relying_party.go +++ b/auth/services/oauth/relying_party.go @@ -167,11 +167,19 @@ func (s *relyingParty) RequestRFC021AccessToken(ctx context.Context, requestHold } expires := time.Now().Add(time.Minute * 15) //todo nonce := generateNonce() - vp, err := s.wallet.BuildPresentation(ctx, credentials, holder.PresentationOptions{ProofOptions: proof.ProofOptions{ - Created: time.Now(), - Challenge: &nonce, - Expires: &expires, - }}, &requestHolder, true) + // determine the format to use + format, err := determineFormat(metadata.VPFormats) + if err != nil { + return nil, err + } + vp, err := s.wallet.BuildPresentation(ctx, credentials, holder.PresentationOptions{ + Format: format, + ProofOptions: proof.ProofOptions{ + Created: time.Now(), + Challenge: &nonce, + Expires: &expires, + }, + }, &requestHolder, true) if err != nil { return nil, fmt.Errorf("failed to create verifiable presentation: %w", err) } @@ -189,6 +197,23 @@ func (s *relyingParty) RequestRFC021AccessToken(ctx context.Context, requestHold }, nil } +func determineFormat(formats map[string]map[string][]string) (format string, err error) { + for format = range formats { + switch format { + case "jwt_vp_json": + fallthrough + case "jwt_vp": + fallthrough + case "ldp_vp": + return + default: + err = errors.New("unsupported format") + } + } + err = errors.New("authorization server metadata does not contain any supported formats") + return +} + var timeFunc = time.Now // standalone func for easier testing diff --git a/vcr/holder/openid_test.go b/vcr/holder/openid_test.go index e1d7465cde..d05f3539fa 100644 --- a/vcr/holder/openid_test.go +++ b/vcr/holder/openid_test.go @@ -95,7 +95,7 @@ func Test_wallet_HandleCredentialOffer(t *testing.T) { jwtSigner.EXPECT().SignJWT(gomock.Any(), map[string]interface{}{ "aud": issuerDID.String(), "iat": int64(1735689600), - "nonce": nonce, + "nonce": &nonce, }, gomock.Any(), "key-id").Return("signed-jwt", nil) keyResolver := resolver.NewMockKeyResolver(ctrl) keyResolver.EXPECT().ResolveKey(holderDID, nil, resolver.NutsSigningKeyType).Return(ssi.MustParseURI("key-id"), nil, nil)