diff --git a/packages/client/lib/AuthorizationCodeClient.ts b/packages/client/lib/AuthorizationCodeClient.ts index 1d68335a..2135286d 100644 --- a/packages/client/lib/AuthorizationCodeClient.ts +++ b/packages/client/lib/AuthorizationCodeClient.ts @@ -27,7 +27,7 @@ export const createAuthorizationRequestUrl = async ({ credentialOffer?: CredentialOfferRequestWithBaseUrl; credentialsSupported?: CredentialSupported[]; }): Promise => { - const { redirectUri } = authorizationRequest; + const { redirectUri, clientId } = authorizationRequest; let { scope, authorizationDetails } = authorizationRequest; const parMode = endpointMetadata?.credentialIssuerMetadata?.require_pushed_authorization_requests ? PARMode.REQUIRE @@ -78,17 +78,12 @@ export const createAuthorizationRequestUrl = async ({ code_challenge: pkce.codeChallenge, }), authorization_details: JSON.stringify(handleAuthorizationDetails(endpointMetadata, authorizationDetails)), - redirect_uri: redirectUri, + ...(redirectUri && { redirect_uri: redirectUri }), + ...(clientId && { client_id: clientId }), + ...(credentialOffer?.issuerState && { issuer_state: credentialOffer.issuerState }), scope, }; - if (authorizationRequest.clientId) { - queryObj['client_id'] = authorizationRequest.clientId; - } - - if (credentialOffer?.issuerState) { - queryObj['issuer_state'] = credentialOffer.issuerState; - } if (!parEndpoint && parMode === PARMode.REQUIRE) { throw Error(`PAR mode is set to required by Authorization Server does not support PAR!`); } else if (parEndpoint && parMode !== PARMode.NEVER) { diff --git a/packages/client/lib/OpenID4VCIClient.ts b/packages/client/lib/OpenID4VCIClient.ts index b8f4a015..7d325dd6 100644 --- a/packages/client/lib/OpenID4VCIClient.ts +++ b/packages/client/lib/OpenID4VCIClient.ts @@ -9,6 +9,7 @@ import { CredentialOfferRequestWithBaseUrl, CredentialResponse, CredentialSupported, + DefaultURISchemes, EndpointMetadataResult, getClientIdFromCredentialOfferPayload, getIssuerFromCredentialOfferPayload, @@ -541,15 +542,14 @@ export class OpenID4VCIClient { private syncAuthorizationRequestOpts(opts?: AuthorizationRequestOpts): AuthorizationRequestOpts { let authorizationRequestOpts = { ...this._authorizationRequestOpts, ...opts } as AuthorizationRequestOpts; if (!authorizationRequestOpts) { - authorizationRequestOpts = { redirectUri: 'openid4vc://' }; + // We only set a redirectUri if no options are provided. + // Note that this only works for mobile apps, that can handle a code query param on the default openid-credential-offer deeplink. + // Provide your own options if that is not desired! + authorizationRequestOpts = { redirectUri: `${DefaultURISchemes.CREDENTIAL_OFFER}://` }; } const clientId = authorizationRequestOpts.clientId ?? this._clientId; this._clientId = clientId; authorizationRequestOpts.clientId = clientId; - - if (!authorizationRequestOpts.redirectUri) { - authorizationRequestOpts.redirectUri = 'openid4vc://'; - } return authorizationRequestOpts; } } diff --git a/packages/client/lib/__tests__/OpenID4VCIClient.spec.ts b/packages/client/lib/__tests__/OpenID4VCIClient.spec.ts index 9347725f..2f6e6b81 100644 --- a/packages/client/lib/__tests__/OpenID4VCIClient.spec.ts +++ b/packages/client/lib/__tests__/OpenID4VCIClient.spec.ts @@ -140,7 +140,7 @@ describe('OpenID4VCIClient should', () => { }, }), ).resolves.toEqual( - 'https://server.example.com/v1/auth/authorize?response_type=code&code_challenge_method=S256&code_challenge=mE2kPHmIprOqtkaYmESWj35yz-PB5vzdiSu0tAZ8sqs&authorization_details=%5B%7B%22type%22%3A%22openid_credential%22%2C%22format%22%3A%22ldp_vc%22%2C%22credential_definition%22%3A%7B%22%40context%22%3A%5B%22https%3A%2F%2Fwww%2Ew3%2Eorg%2F2018%2Fcredentials%2Fv1%22%2C%22https%3A%2F%2Fwww%2Ew3%2Eorg%2F2018%2Fcredentials%2Fexamples%2Fv1%22%5D%2C%22types%22%3A%5B%22VerifiableCredential%22%2C%22UniversityDegreeCredential%22%5D%7D%2C%22locations%22%3A%5B%22https%3A%2F%2Fserver%2Eexample%2Ecom%22%5D%7D%2C%7B%22type%22%3A%22openid_credential%22%2C%22format%22%3A%22mso_mdoc%22%2C%22doctype%22%3A%22org%2Eiso%2E18013%2E5%2E1%2EmDL%22%2C%22locations%22%3A%5B%22https%3A%2F%2Fserver%2Eexample%2Ecom%22%5D%7D%5D&redirect_uri=http%3A%2F%2Flocalhost%3A8881%2Fcb&scope=openid&client_id=test-client', + 'https://server.example.com/v1/auth/authorize?response_type=code&code_challenge_method=S256&code_challenge=mE2kPHmIprOqtkaYmESWj35yz-PB5vzdiSu0tAZ8sqs&authorization_details=%5B%7B%22type%22%3A%22openid_credential%22%2C%22format%22%3A%22ldp_vc%22%2C%22credential_definition%22%3A%7B%22%40context%22%3A%5B%22https%3A%2F%2Fwww%2Ew3%2Eorg%2F2018%2Fcredentials%2Fv1%22%2C%22https%3A%2F%2Fwww%2Ew3%2Eorg%2F2018%2Fcredentials%2Fexamples%2Fv1%22%5D%2C%22types%22%3A%5B%22VerifiableCredential%22%2C%22UniversityDegreeCredential%22%5D%7D%2C%22locations%22%3A%5B%22https%3A%2F%2Fserver%2Eexample%2Ecom%22%5D%7D%2C%7B%22type%22%3A%22openid_credential%22%2C%22format%22%3A%22mso_mdoc%22%2C%22doctype%22%3A%22org%2Eiso%2E18013%2E5%2E1%2EmDL%22%2C%22locations%22%3A%5B%22https%3A%2F%2Fserver%2Eexample%2Ecom%22%5D%7D%5D&redirect_uri=http%3A%2F%2Flocalhost%3A8881%2Fcb&client_id=test-client&scope=openid', ); }); it('create an authorization request url with authorization_details object property', async () => { @@ -167,7 +167,7 @@ describe('OpenID4VCIClient should', () => { }, }), ).resolves.toEqual( - 'https://server.example.com/v1/auth/authorize?response_type=code&code_challenge_method=S256&code_challenge=mE2kPHmIprOqtkaYmESWj35yz-PB5vzdiSu0tAZ8sqs&authorization_details=%7B%22type%22%3A%22openid_credential%22%2C%22format%22%3A%22ldp_vc%22%2C%22credential_definition%22%3A%7B%22%40context%22%3A%5B%22https%3A%2F%2Fwww%2Ew3%2Eorg%2F2018%2Fcredentials%2Fv1%22%2C%22https%3A%2F%2Fwww%2Ew3%2Eorg%2F2018%2Fcredentials%2Fexamples%2Fv1%22%5D%2C%22types%22%3A%5B%22VerifiableCredential%22%2C%22UniversityDegreeCredential%22%5D%7D%2C%22locations%22%3A%5B%22https%3A%2F%2Fserver%2Eexample%2Ecom%22%5D%7D&redirect_uri=http%3A%2F%2Flocalhost%3A8881%2Fcb&scope=openid&client_id=test-client', + 'https://server.example.com/v1/auth/authorize?response_type=code&code_challenge_method=S256&code_challenge=mE2kPHmIprOqtkaYmESWj35yz-PB5vzdiSu0tAZ8sqs&authorization_details=%7B%22type%22%3A%22openid_credential%22%2C%22format%22%3A%22ldp_vc%22%2C%22credential_definition%22%3A%7B%22%40context%22%3A%5B%22https%3A%2F%2Fwww%2Ew3%2Eorg%2F2018%2Fcredentials%2Fv1%22%2C%22https%3A%2F%2Fwww%2Ew3%2Eorg%2F2018%2Fcredentials%2Fexamples%2Fv1%22%5D%2C%22types%22%3A%5B%22VerifiableCredential%22%2C%22UniversityDegreeCredential%22%5D%7D%2C%22locations%22%3A%5B%22https%3A%2F%2Fserver%2Eexample%2Ecom%22%5D%7D&redirect_uri=http%3A%2F%2Flocalhost%3A8881%2Fcb&client_id=test-client&scope=openid', ); }); it('create an authorization request url with authorization_details and scope', async () => { @@ -196,7 +196,7 @@ describe('OpenID4VCIClient should', () => { }, }), ).resolves.toEqual( - 'https://server.example.com/v1/auth/authorize?response_type=code&code_challenge_method=S256&code_challenge=mE2kPHmIprOqtkaYmESWj35yz-PB5vzdiSu0tAZ8sqs&authorization_details=%7B%22type%22%3A%22openid_credential%22%2C%22format%22%3A%22ldp_vc%22%2C%22locations%22%3A%5B%22https%3A%2F%2Ftest%2Ecom%22%2C%22https%3A%2F%2Fserver%2Eexample%2Ecom%22%5D%2C%22credential_definition%22%3A%7B%22%40context%22%3A%5B%22https%3A%2F%2Fwww%2Ew3%2Eorg%2F2018%2Fcredentials%2Fv1%22%2C%22https%3A%2F%2Fwww%2Ew3%2Eorg%2F2018%2Fcredentials%2Fexamples%2Fv1%22%5D%2C%22types%22%3A%5B%22VerifiableCredential%22%2C%22UniversityDegreeCredential%22%5D%7D%7D&redirect_uri=http%3A%2F%2Flocalhost%3A8881%2Fcb&scope=openid&client_id=test-client', + 'https://server.example.com/v1/auth/authorize?response_type=code&code_challenge_method=S256&code_challenge=mE2kPHmIprOqtkaYmESWj35yz-PB5vzdiSu0tAZ8sqs&authorization_details=%7B%22type%22%3A%22openid_credential%22%2C%22format%22%3A%22ldp_vc%22%2C%22locations%22%3A%5B%22https%3A%2F%2Ftest%2Ecom%22%2C%22https%3A%2F%2Fserver%2Eexample%2Ecom%22%5D%2C%22credential_definition%22%3A%7B%22%40context%22%3A%5B%22https%3A%2F%2Fwww%2Ew3%2Eorg%2F2018%2Fcredentials%2Fv1%22%2C%22https%3A%2F%2Fwww%2Ew3%2Eorg%2F2018%2Fcredentials%2Fexamples%2Fv1%22%5D%2C%22types%22%3A%5B%22VerifiableCredential%22%2C%22UniversityDegreeCredential%22%5D%7D%7D&redirect_uri=http%3A%2F%2Flocalhost%3A8881%2Fcb&client_id=test-client&scope=openid', ); }); }); diff --git a/packages/common/lib/types/Authorization.types.ts b/packages/common/lib/types/Authorization.types.ts index cb3a98b0..450ac4c4 100644 --- a/packages/common/lib/types/Authorization.types.ts +++ b/packages/common/lib/types/Authorization.types.ts @@ -254,7 +254,7 @@ export interface AuthorizationRequestOpts { pkce?: PKCEOpts; parMode?: PARMode; authorizationDetails?: AuthorizationDetails | AuthorizationDetails[]; - redirectUri: string; + redirectUri?: string; scope?: string; }