Skip to content

Commit

Permalink
fix: Better match credential offer types and formats onto issuer meta…
Browse files Browse the repository at this point in the history
…data
  • Loading branch information
nklomp committed Sep 27, 2023
1 parent ff30029 commit 4044c21
Show file tree
Hide file tree
Showing 13 changed files with 139 additions and 211 deletions.
7 changes: 1 addition & 6 deletions packages/callback-example/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,9 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline

# [0.7.0](https://github.com/Sphereon-Opensource/OID4VCI/compare/v0.6.0...v0.7.0) (2023-08-19)


### Features

* Integrate ssi-express-support to allow for future authn/authz. Also moved endpoints to functions, so solutions can include their own set of endpoints ([c749aba](https://github.com/Sphereon-Opensource/OID4VCI/commit/c749ababd4bec567d6aeeda49b76f195ec792201))




- Integrate ssi-express-support to allow for future authn/authz. Also moved endpoints to functions, so solutions can include their own set of endpoints ([c749aba](https://github.com/Sphereon-Opensource/OID4VCI/commit/c749ababd4bec567d6aeeda49b76f195ec792201))

# [0.6.0](https://github.com/Sphereon-Opensource/OID4VCI/compare/v0.4.0...v0.6.0) (2023-06-24)

Expand Down
10 changes: 2 additions & 8 deletions packages/client/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,13 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline

# [0.7.0](https://github.com/Sphereon-Opensource/OID4VCI/compare/v0.6.0...v0.7.0) (2023-08-19)


### Bug Fixes

* Revise well-known metadata retrieval for OID4VCI, OAuth 2.0 and OIDC. fixes [#62](https://github.com/Sphereon-Opensource/OID4VCI/issues/62) ([a750cc7](https://github.com/Sphereon-Opensource/OID4VCI/commit/a750cc76e084f12aeb58f2b1ac44b1bb5e69b5ae))

- Revise well-known metadata retrieval for OID4VCI, OAuth 2.0 and OIDC. fixes [#62](https://github.com/Sphereon-Opensource/OID4VCI/issues/62) ([a750cc7](https://github.com/Sphereon-Opensource/OID4VCI/commit/a750cc76e084f12aeb58f2b1ac44b1bb5e69b5ae))

### Features

* Integrate ssi-express-support to allow for future authn/authz. Also moved endpoints to functions, so solutions can include their own set of endpoints ([c749aba](https://github.com/Sphereon-Opensource/OID4VCI/commit/c749ababd4bec567d6aeeda49b76f195ec792201))




- Integrate ssi-express-support to allow for future authn/authz. Also moved endpoints to functions, so solutions can include their own set of endpoints ([c749aba](https://github.com/Sphereon-Opensource/OID4VCI/commit/c749ababd4bec567d6aeeda49b76f195ec792201))

# [0.6.0](https://github.com/Sphereon-Opensource/OID4VCI/compare/v0.4.0...v0.6.0) (2023-06-24)

Expand Down
80 changes: 15 additions & 65 deletions packages/client/lib/OpenID4VCIClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -366,79 +366,29 @@ export class OpenID4VCIClient {
return response.successBody;
}

getCredentialsSupported(restrictToInitiationTypes: boolean, supportedType?: string): CredentialSupported[] {
getCredentialsSupported(
restrictToInitiationTypes: boolean,
format?: (OID4VCICredentialFormat | string) | (OID4VCICredentialFormat | string)[],
): CredentialSupported[] {
return getSupportedCredentials({
issuerMetadata: this.endpointMetadata.credentialIssuerMetadata,
version: this.version(),
supportedType,
credentialTypes: restrictToInitiationTypes ? this.getCredentialTypes() : undefined,
format: format,
types: restrictToInitiationTypes ? this.getCredentialTypes() : undefined,
});
/*//FIXME: delegate to getCredentialsSupported from IssuerMetadataUtils
let credentialsSupported = this.endpointMetadata?.issuerMetadata?.credentials_supported
if (this.version() === OpenId4VCIVersion.VER_1_0_08 || typeof credentialsSupported === 'object') {
const issuerMetadata = this.endpointMetadata.issuerMetadata as IssuerMetadataV1_0_08
const v8CredentialsSupported = issuerMetadata.credentials_supported
credentialsSupported = []
credentialsSupported = Object.entries(v8CredentialsSupported).map((key, value) => )
}
if (!credentialsSupported) {
return []
} else if (!restrictToInitiationTypes) {
return credentialsSupported
}
/!**
* the following (not array part is a legacy code from version 1_0-08 which jff implementors used)
*!/
if (!Array.isArray(credentialsSupported)) {
const credentialsSupportedV8: CredentialSupportedV1_0_08 = credentialsSupported as CredentialSupportedV1_0_08;
const initiationTypes = supportedType ? [supportedType] : this.getCredentialTypes();
const supported: IssuerCredentialSubject = {};
for (const [key, value] of Object.entries(credentialsSupportedV8)) {
if (initiationTypes.includes(key)) {
supported[key] = value;
}
}
// todo: fix this later. we're returning CredentialSupportedV1_0_08 as a list of CredentialSupported (for v09 onward)
return supported as unknown as CredentialSupported[];
}
const initiationTypes = supportedType ? [supportedType] : this.getCredentialTypes()
const credentialSupportedOverlap: CredentialSupported[] = []
for (const supported of credentialsSupported) {
const supportedTypeOverlap: string[] = []
for (const type of supported.types) {
initiationTypes.includes(type)
supportedTypeOverlap.push(type)
}
if (supportedTypeOverlap.length > 0) {
credentialSupportedOverlap.push({
...supported,
types: supportedTypeOverlap
})
}
}
return credentialSupportedOverlap as CredentialSupported[]*/
}

getCredentialMetadata(type: string): CredentialSupported[] {
return this.getCredentialsSupported(false, type);
}

// todo https://sphereon.atlassian.net/browse/VDX-184
getCredentialTypes(): string[] {
getCredentialTypes(): string[][] {
if (this.credentialOffer.version < OpenId4VCIVersion.VER_1_0_11) {
return typeof (this.credentialOffer.original_credential_offer as CredentialOfferPayloadV1_0_08).credential_type === 'string'
? [(this.credentialOffer.original_credential_offer as CredentialOfferPayloadV1_0_08).credential_type as string]
: ((this.credentialOffer.original_credential_offer as CredentialOfferPayloadV1_0_08).credential_type as string[]);
const orig = this.credentialOffer.original_credential_offer as CredentialOfferPayloadV1_0_08;
const types: string[] = typeof orig.credential_type === 'string' ? [orig.credential_type] : orig.credential_type;
const result: string[][] = [];
result[0] = types;
return result;
} else {
// FIXME: this for sure isn't correct. It would also include VerifiableCredential. The whole call to this getCredentialsTypes should be changed to begin with
return this.credentialOffer.credential_offer.credentials.flatMap((c) => (typeof c === 'string' ? c : c.types));
return this.credentialOffer.credential_offer.credentials.map((c, index) => {
return typeof c === 'string' ? [c] : c.types;
});
}
}

Expand Down
4 changes: 2 additions & 2 deletions packages/client/lib/__tests__/AccessTokenClient.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ import {
AccessTokenResponse,
GrantTypes,
OpenIDResponse,
WellKnownEndpoints
} from '@sphereon/oid4vci-common'
WellKnownEndpoints,
} from '@sphereon/oid4vci-common';
import nock from 'nock';

import { AccessTokenClient } from '../AccessTokenClient';
Expand Down
5 changes: 3 additions & 2 deletions packages/client/lib/__tests__/IT.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,9 @@ import {
CredentialOfferRequestWithBaseUrl,
Jwt,
OpenId4VCIVersion,
ProofOfPossession, WellKnownEndpoints
} from '@sphereon/oid4vci-common'
ProofOfPossession,
WellKnownEndpoints,
} from '@sphereon/oid4vci-common';
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
import nock from 'nock';
Expand Down
49 changes: 23 additions & 26 deletions packages/client/lib/__tests__/MattrE2E.spec.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { CredentialMapper } from '@sphereon/ssi-types'
import { fetch } from 'cross-fetch';
import { Alg, AuthzFlowType, Jwt } from '@sphereon/oid4vci-common';
import { CredentialMapper } from '@sphereon/ssi-types';
import { fetch } from 'cross-fetch';
import { importJWK, JWK, SignJWT } from 'jose';

import { OpenID4VCIClient } from '..';
Expand All @@ -22,53 +22,50 @@ const did = `did:key:z6Mki5ZwZKN1dBQprfJTikUvkDxrHijiiQngkWviMF5gw2Hv`;
const kid = `${did}#z6Mki5ZwZKN1dBQprfJTikUvkDxrHijiiQngkWviMF5gw2Hv`;
describe('OID4VCI-Client using Mattr issuer should', () => {
async function test(format: 'ldp_vc' | 'jwt_vc_json') {
const offer = await getCredentialOffer(format)
const offer = await getCredentialOffer(format);
const client = await OpenID4VCIClient.fromURI({
uri: offer.offerUrl,
flowType: AuthzFlowType.PRE_AUTHORIZED_CODE_FLOW,
kid,
alg: Alg.EdDSA
})
expect(client.flowType).toEqual(AuthzFlowType.PRE_AUTHORIZED_CODE_FLOW)
expect(client.credentialOffer).toBeDefined()
expect(client.endpointMetadata).toBeDefined()
expect(client.getCredentialEndpoint()).toEqual(`${ISSUER_URL}/oidc/v1/auth/credential`)
expect(client.getAccessTokenEndpoint()).toEqual('https://launchpad.vii.electron.mattrlabs.io/oidc/v1/auth/token')

const accessToken = await client.acquireAccessToken()
console.log(accessToken)
alg: Alg.EdDSA,
});
expect(client.flowType).toEqual(AuthzFlowType.PRE_AUTHORIZED_CODE_FLOW);
expect(client.credentialOffer).toBeDefined();
expect(client.endpointMetadata).toBeDefined();
expect(client.getCredentialEndpoint()).toEqual(`${ISSUER_URL}/oidc/v1/auth/credential`);
expect(client.getAccessTokenEndpoint()).toEqual('https://launchpad.vii.electron.mattrlabs.io/oidc/v1/auth/token');

const accessToken = await client.acquireAccessToken();
console.log(accessToken);
expect(accessToken).toMatchObject({
expires_in: 3600,
scope: 'OpenBadgeCredential',
token_type: 'Bearer'
})
token_type: 'Bearer',
});

const credentialResponse = await client.acquireCredentials({
credentialTypes: 'OpenBadgeCredential',
format,
proofCallbacks: {
signCallback: proofOfPossessionCallbackFunction
}
})
expect(credentialResponse.credential).toBeDefined()
const wrappedVC = CredentialMapper.toWrappedVerifiableCredential(credentialResponse.credential!)
expect(format.startsWith(wrappedVC.format)).toEqual(true)

signCallback: proofOfPossessionCallbackFunction,
},
});
expect(credentialResponse.credential).toBeDefined();
const wrappedVC = CredentialMapper.toWrappedVerifiableCredential(credentialResponse.credential!);
expect(format.startsWith(wrappedVC.format)).toEqual(true);
}

it(
'succeed in a full flow with the client using OpenID4VCI version 11 and ldp_vc',
async () => {

await test('ldp_vc')
await test('ldp_vc');
},
UNIT_TEST_TIMEOUT,
);
it(
'succeed in a full flow with the client using OpenID4VCI version 11 and jwt_vc_json',
async () => {

await test('jwt_vc_json')
await test('jwt_vc_json');
},
UNIT_TEST_TIMEOUT,
);
Expand Down
2 changes: 1 addition & 1 deletion packages/client/lib/__tests__/OpenID4VCIClient.spec.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { AuthzFlowType, CodeChallengeMethod, WellKnownEndpoints } from '@sphereon/oid4vci-common'
import { AuthzFlowType, CodeChallengeMethod, WellKnownEndpoints } from '@sphereon/oid4vci-common';
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
import nock from 'nock';
Expand Down
18 changes: 5 additions & 13 deletions packages/client/lib/__tests__/OpenID4VCIClientPAR.spec.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { AuthzFlowType, CodeChallengeMethod, WellKnownEndpoints } from '@sphereon/oid4vci-common'
import { AuthzFlowType, CodeChallengeMethod, WellKnownEndpoints } from '@sphereon/oid4vci-common';
import nock from 'nock';

import { OpenID4VCIClient } from '../OpenID4VCIClient';
Expand All @@ -23,9 +23,7 @@ describe('OpenID4VCIClient', () => {
});

it('should successfully retrieve the authorization code using PAR', async () => {
(
client.endpointMetadata.credentialIssuerMetadata!
).pushed_authorization_request_endpoint = `${MOCK_URL}v1/auth/par`;
client.endpointMetadata.credentialIssuerMetadata!.pushed_authorization_request_endpoint = `${MOCK_URL}v1/auth/par`;
const actual = await client.acquirePushedAuthorizationRequestURI({
clientId: 'test-client',
codeChallengeMethod: CodeChallengeMethod.SHA256,
Expand Down Expand Up @@ -60,9 +58,7 @@ describe('OpenID4VCIClient', () => {
});

it('should not fail when only authorization_details is present', async () => {
(
client.endpointMetadata.credentialIssuerMetadata!
).pushed_authorization_request_endpoint = `${MOCK_URL}v1/auth/par`;
client.endpointMetadata.credentialIssuerMetadata!.pushed_authorization_request_endpoint = `${MOCK_URL}v1/auth/par`;
const actual = await client.acquirePushedAuthorizationRequestURI({
clientId: 'test-client',
codeChallengeMethod: CodeChallengeMethod.SHA256,
Expand All @@ -83,9 +79,7 @@ describe('OpenID4VCIClient', () => {
});

it('should not fail when only scope is present', async () => {
(
client.endpointMetadata.credentialIssuerMetadata!
).pushed_authorization_request_endpoint = `${MOCK_URL}v1/auth/par`;
client.endpointMetadata.credentialIssuerMetadata!.pushed_authorization_request_endpoint = `${MOCK_URL}v1/auth/par`;
const actual = await client.acquirePushedAuthorizationRequestURI({
clientId: 'test-client',
codeChallengeMethod: CodeChallengeMethod.SHA256,
Expand All @@ -97,9 +91,7 @@ describe('OpenID4VCIClient', () => {
});

it('should not fail when both authorization_details and scope are present', async () => {
(
client.endpointMetadata.credentialIssuerMetadata!
).pushed_authorization_request_endpoint = `${MOCK_URL}v1/auth/par`;
client.endpointMetadata.credentialIssuerMetadata!.pushed_authorization_request_endpoint = `${MOCK_URL}v1/auth/par`;
const actual = await client.acquirePushedAuthorizationRequestURI({
clientId: 'test-client',
codeChallengeMethod: CodeChallengeMethod.SHA256,
Expand Down
12 changes: 3 additions & 9 deletions packages/common/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,14 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline

# [0.7.0](https://github.com/Sphereon-Opensource/OID4VCI/compare/v0.6.0...v0.7.0) (2023-08-19)


### Bug Fixes

* fix credential request properties ([0037025](https://github.com/Sphereon-Opensource/OID4VCI/commit/0037025ef27d3a1fa7c68954b1f87e660ef0c82c))
* Revise well-known metadata retrieval for OID4VCI, OAuth 2.0 and OIDC. fixes [#62](https://github.com/Sphereon-Opensource/OID4VCI/issues/62) ([a750cc7](https://github.com/Sphereon-Opensource/OID4VCI/commit/a750cc76e084f12aeb58f2b1ac44b1bb5e69b5ae))

- fix credential request properties ([0037025](https://github.com/Sphereon-Opensource/OID4VCI/commit/0037025ef27d3a1fa7c68954b1f87e660ef0c82c))
- Revise well-known metadata retrieval for OID4VCI, OAuth 2.0 and OIDC. fixes [#62](https://github.com/Sphereon-Opensource/OID4VCI/issues/62) ([a750cc7](https://github.com/Sphereon-Opensource/OID4VCI/commit/a750cc76e084f12aeb58f2b1ac44b1bb5e69b5ae))

### Features

* Integrate ssi-express-support to allow for future authn/authz. Also moved endpoints to functions, so solutions can include their own set of endpoints ([c749aba](https://github.com/Sphereon-Opensource/OID4VCI/commit/c749ababd4bec567d6aeeda49b76f195ec792201))




- Integrate ssi-express-support to allow for future authn/authz. Also moved endpoints to functions, so solutions can include their own set of endpoints ([c749aba](https://github.com/Sphereon-Opensource/OID4VCI/commit/c749ababd4bec567d6aeeda49b76f195ec792201))

# [0.6.0](https://github.com/Sphereon-Opensource/OID4VCI/compare/v0.4.0...v0.6.0) (2023-06-24)

Expand Down
Loading

0 comments on commit 4044c21

Please sign in to comment.