@sphereon/oid4vci-client 0.7.0 → 0.7.1-next.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { OpenId4VCIVersion } from '@sphereon/oid4vci-common';
|
|
2
|
+
|
|
1
3
|
import { CredentialOfferClient } from '../CredentialOfferClient';
|
|
2
4
|
|
|
3
5
|
import { INITIATION_TEST, INITIATION_TEST_HTTPS_URI, INITIATION_TEST_URI } from './MetadataMocks';
|
|
@@ -45,4 +47,15 @@ describe('Issuance Initiation', () => {
|
|
|
45
47
|
const issuanceInitiationURI = INITIATION_TEST_HTTPS_URI.replace('?', '');
|
|
46
48
|
await expect(async () => CredentialOfferClient.fromURI(issuanceInitiationURI)).rejects.toThrowError('Invalid Credential Offer Request');
|
|
47
49
|
});
|
|
50
|
+
|
|
51
|
+
it('Should return Credential Offer', async () => {
|
|
52
|
+
const client = await CredentialOfferClient.fromURI(
|
|
53
|
+
'openid-credential-offer://?credential_offer=%7B%22credential_issuer%22%3A%22https%3A%2F%2Flaunchpad.vii.electron.mattrlabs.io%22%2C%22credentials%22%3A%5B%7B%22format%22%3A%22ldp_vc%22%2C%22types%22%3A%5B%22OpenBadgeCredential%22%5D%7D%5D%2C%22grants%22%3A%7B%22urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Apre-authorized_code%22%3A%7B%22pre-authorized_code%22%3A%22UPZohaodPlLBnGsqB02n2tIupCIg8nKRRUEUHWA665X%22%7D%7D%7D',
|
|
54
|
+
);
|
|
55
|
+
expect(client.version).toEqual(OpenId4VCIVersion.VER_1_0_11);
|
|
56
|
+
expect(client.baseUrl).toEqual('openid-credential-offer://');
|
|
57
|
+
expect(client.scheme).toEqual('openid-credential-offer');
|
|
58
|
+
expect(client.credential_offer.credential_issuer).toEqual('https://launchpad.vii.electron.mattrlabs.io');
|
|
59
|
+
expect(client.preAuthorizedCode).toEqual('UPZohaodPlLBnGsqB02n2tIupCIg8nKRRUEUHWA665X');
|
|
60
|
+
});
|
|
48
61
|
});
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import { fetch } from 'cross-fetch';
|
|
2
|
+
import { Alg, AuthzFlowType, Jwt } from '@sphereon/oid4vci-common';
|
|
3
|
+
import { importJWK, JWK, SignJWT } from 'jose';
|
|
4
|
+
|
|
5
|
+
import { OpenID4VCIClient } from '..';
|
|
6
|
+
|
|
7
|
+
export const UNIT_TEST_TIMEOUT = 30000;
|
|
8
|
+
|
|
9
|
+
const ISSUER_URL = 'https://launchpad.vii.electron.mattrlabs.io';
|
|
10
|
+
|
|
11
|
+
const jwk: JWK = {
|
|
12
|
+
crv: 'Ed25519',
|
|
13
|
+
d: 'kTRm0aONHYwNPA-w_DtjMHUIWjE3K70qgCIhWojZ0eU',
|
|
14
|
+
x: 'NeA0d8sp86xRh3DczU4m5wPNIbl0HCSwOBcMN3sNmdk',
|
|
15
|
+
kty: 'OKP',
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
// pub hex: 35e03477cb29f3ac518770dccd4e26e703cd21b9741c24b038170c377b0d99d9
|
|
19
|
+
// priv hex: 913466d1a38d1d8c0d3c0fb0fc3b633075085a31372bbd2a8022215a88d9d1e5
|
|
20
|
+
const did = `did:key:z6Mki5ZwZKN1dBQprfJTikUvkDxrHijiiQngkWviMF5gw2Hv`;
|
|
21
|
+
const kid = `${did}#z6Mki5ZwZKN1dBQprfJTikUvkDxrHijiiQngkWviMF5gw2Hv`;
|
|
22
|
+
describe('OID4VCI-Client using Mattr issuer should', () => {
|
|
23
|
+
async function test(format: 'ldp_vc' | 'jwt_vc_json') {
|
|
24
|
+
const offer = await getCredentialOffer(format)
|
|
25
|
+
const client = await OpenID4VCIClient.fromURI({
|
|
26
|
+
uri: offer.offerUrl,
|
|
27
|
+
flowType: AuthzFlowType.PRE_AUTHORIZED_CODE_FLOW,
|
|
28
|
+
kid,
|
|
29
|
+
alg: Alg.EdDSA
|
|
30
|
+
})
|
|
31
|
+
expect(client.flowType).toEqual(AuthzFlowType.PRE_AUTHORIZED_CODE_FLOW)
|
|
32
|
+
expect(client.credentialOffer).toBeDefined()
|
|
33
|
+
expect(client.endpointMetadata).toBeDefined()
|
|
34
|
+
expect(client.getCredentialEndpoint()).toEqual(`${ISSUER_URL}/oidc/v1/auth/credential`)
|
|
35
|
+
expect(client.getAccessTokenEndpoint()).toEqual('https://launchpad.vii.electron.mattrlabs.io/oidc/v1/auth/token')
|
|
36
|
+
|
|
37
|
+
const accessToken = await client.acquireAccessToken()
|
|
38
|
+
console.log(accessToken)
|
|
39
|
+
expect(accessToken).toMatchObject({
|
|
40
|
+
expires_in: 3600,
|
|
41
|
+
scope: 'OpenBadgeCredential',
|
|
42
|
+
token_type: 'Bearer'
|
|
43
|
+
})
|
|
44
|
+
|
|
45
|
+
const credentialResponse = await client.acquireCredentials({
|
|
46
|
+
credentialTypes: 'OpenBadgeCredential',
|
|
47
|
+
format,
|
|
48
|
+
proofCallbacks: {
|
|
49
|
+
signCallback: proofOfPossessionCallbackFunction
|
|
50
|
+
}
|
|
51
|
+
})
|
|
52
|
+
expect(credentialResponse.credential).toBeDefined()
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
it(
|
|
56
|
+
'succeed in a full flow with the client using OpenID4VCI version 11 and ldp_vc',
|
|
57
|
+
async () => {
|
|
58
|
+
|
|
59
|
+
await test('ldp_vc')
|
|
60
|
+
},
|
|
61
|
+
UNIT_TEST_TIMEOUT,
|
|
62
|
+
);
|
|
63
|
+
it(
|
|
64
|
+
'succeed in a full flow with the client using OpenID4VCI version 11 and jwt_vc_json',
|
|
65
|
+
async () => {
|
|
66
|
+
|
|
67
|
+
await test('jwt_vc_json')
|
|
68
|
+
},
|
|
69
|
+
UNIT_TEST_TIMEOUT,
|
|
70
|
+
);
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
interface CreateCredentialOfferResponse {
|
|
74
|
+
id: string;
|
|
75
|
+
offerUrl: string;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
async function getCredentialOffer(format: 'ldp_vc' | 'jwt_vc_json'): Promise<CreateCredentialOfferResponse> {
|
|
79
|
+
const credentialOffer = await fetch('https://launchpad.mattrlabs.com/api/credential-offer', {
|
|
80
|
+
method: 'post',
|
|
81
|
+
headers: {
|
|
82
|
+
Accept: 'application/json',
|
|
83
|
+
'Content-Type': 'application/json',
|
|
84
|
+
},
|
|
85
|
+
|
|
86
|
+
//make sure to serialize your JSON body
|
|
87
|
+
body: JSON.stringify({
|
|
88
|
+
format,
|
|
89
|
+
type: 'OpenBadgeCredential',
|
|
90
|
+
userId: '622a9f65-21c0-4c0b-9a6a-f7574c2a1549',
|
|
91
|
+
userAuthenticationRequired: false,
|
|
92
|
+
}),
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
return (await credentialOffer.json()) as CreateCredentialOfferResponse;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
async function proofOfPossessionCallbackFunction(args: Jwt, kid?: string): Promise<string> {
|
|
99
|
+
const importedJwk = await importJWK(jwk, 'EdDSA');
|
|
100
|
+
return await new SignJWT({ ...args.payload })
|
|
101
|
+
.setProtectedHeader({ ...args.header })
|
|
102
|
+
.setIssuedAt()
|
|
103
|
+
.setExpirationTime('2h')
|
|
104
|
+
.sign(importedJwk);
|
|
105
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sphereon/oid4vci-client",
|
|
3
|
-
"version": "0.7.
|
|
3
|
+
"version": "0.7.1-next.7+5b8552f",
|
|
4
4
|
"description": "OpenID for Verifiable Credential Issuance (OpenID4VCI) client",
|
|
5
5
|
"source": "lib/index.ts",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -15,15 +15,14 @@
|
|
|
15
15
|
"build": "tsc"
|
|
16
16
|
},
|
|
17
17
|
"dependencies": {
|
|
18
|
-
"@sphereon/oid4vci-common": "0.7.
|
|
18
|
+
"@sphereon/oid4vci-common": "0.7.1-next.7+5b8552f",
|
|
19
19
|
"@sphereon/ssi-types": "^0.15.1",
|
|
20
20
|
"cross-fetch": "^3.1.8",
|
|
21
|
-
"debug": "^4.3.4"
|
|
22
|
-
"uint8arrays": "^4.0.6"
|
|
21
|
+
"debug": "^4.3.4"
|
|
23
22
|
},
|
|
24
23
|
"devDependencies": {
|
|
25
24
|
"@types/jest": "^29.5.3",
|
|
26
|
-
"@types/node": "^18.17.
|
|
25
|
+
"@types/node": "^18.17.4",
|
|
27
26
|
"@typescript-eslint/eslint-plugin": "^5.62.0",
|
|
28
27
|
"@typescript-eslint/parser": "^5.62.0",
|
|
29
28
|
"codecov": "^3.8.3",
|
|
@@ -40,7 +39,8 @@
|
|
|
40
39
|
"open-cli": "^7.2.0",
|
|
41
40
|
"ts-jest": "^29.1.1",
|
|
42
41
|
"ts-node": "^10.9.1",
|
|
43
|
-
"typescript": "4.9.5"
|
|
42
|
+
"typescript": "4.9.5",
|
|
43
|
+
"uint8arrays": "3.1.1"
|
|
44
44
|
},
|
|
45
45
|
"engines": {
|
|
46
46
|
"node": ">=16"
|
|
@@ -64,5 +64,5 @@
|
|
|
64
64
|
"OIDC4VCI",
|
|
65
65
|
"OID4VCI"
|
|
66
66
|
],
|
|
67
|
-
"gitHead": "
|
|
67
|
+
"gitHead": "5b8552f1844e4b97156c49e464693952fd0b63f0"
|
|
68
68
|
}
|