@sphereon/oid4vci-client 0.12.1-unstable.8 → 0.13.0
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.
- package/dist/AccessTokenClient.d.ts.map +1 -1
- package/dist/AccessTokenClient.js +11 -5
- package/dist/AccessTokenClient.js.map +1 -1
- package/dist/AccessTokenClientV1_0_11.d.ts.map +1 -1
- package/dist/AccessTokenClientV1_0_11.js +12 -5
- package/dist/AccessTokenClientV1_0_11.js.map +1 -1
- package/dist/AuthorizationCodeClient.js +2 -2
- package/dist/CredentialRequestClientBuilder.d.ts.map +1 -1
- package/dist/CredentialRequestClientBuilder.js.map +1 -1
- package/dist/OpenID4VCIClient.d.ts +3 -1
- package/dist/OpenID4VCIClient.d.ts.map +1 -1
- package/dist/OpenID4VCIClient.js +30 -14
- package/dist/OpenID4VCIClient.js.map +1 -1
- package/dist/OpenID4VCIClientV1_0_11.d.ts +4 -2
- package/dist/OpenID4VCIClientV1_0_11.d.ts.map +1 -1
- package/dist/OpenID4VCIClientV1_0_11.js +32 -16
- package/dist/OpenID4VCIClientV1_0_11.js.map +1 -1
- package/dist/OpenID4VCIClientV1_0_13.d.ts +3 -1
- package/dist/OpenID4VCIClientV1_0_13.d.ts.map +1 -1
- package/dist/OpenID4VCIClientV1_0_13.js +29 -15
- package/dist/OpenID4VCIClientV1_0_13.js.map +1 -1
- package/dist/ProofOfPossessionBuilder.js +6 -6
- package/dist/ProofOfPossessionBuilder.js.map +1 -1
- package/dist/functions/AccessTokenUtil.d.ts +5 -0
- package/dist/functions/AccessTokenUtil.d.ts.map +1 -0
- package/dist/functions/AccessTokenUtil.js +63 -0
- package/dist/functions/AccessTokenUtil.js.map +1 -0
- package/dist/functions/index.d.ts +2 -0
- package/dist/functions/index.d.ts.map +1 -1
- package/dist/functions/index.js +2 -0
- package/dist/functions/index.js.map +1 -1
- package/lib/AccessTokenClient.ts +9 -4
- package/lib/AccessTokenClientV1_0_11.ts +11 -3
- package/lib/AuthorizationCodeClient.ts +2 -2
- package/lib/CredentialRequestClientBuilder.ts +14 -14
- package/lib/OpenID4VCIClient.ts +31 -3
- package/lib/OpenID4VCIClientV1_0_11.ts +35 -6
- package/lib/OpenID4VCIClientV1_0_13.ts +33 -6
- package/lib/ProofOfPossessionBuilder.ts +6 -6
- package/lib/__tests__/CredentialRequestClient.spec.ts +1 -1
- package/lib/__tests__/CredentialRequestClientBuilder.spec.ts +1 -1
- package/lib/__tests__/CredentialRequestClientV1_0_11.spec.ts +2 -2
- package/lib/__tests__/IT.spec.ts +23 -33
- package/lib/__tests__/ProofOfPossessionBuilder.spec.ts +23 -23
- package/lib/__tests__/SdJwt.spec.ts +26 -26
- package/lib/functions/AccessTokenUtil.ts +52 -0
- package/lib/functions/index.ts +2 -0
- package/package.json +4 -4
|
@@ -8,12 +8,12 @@ import { ProofOfPossessionBuilder } from '..';
|
|
|
8
8
|
import { IDENTIPROOF_ISSUER_URL } from './MetadataMocks';
|
|
9
9
|
|
|
10
10
|
const jwt: Jwt = {
|
|
11
|
-
header: { alg: Alg.ES256, kid: 'did:example:ebfeb1f712ebc6f1c276e12ec21/keys/1', typ: '
|
|
11
|
+
header: { alg: Alg.ES256, kid: 'did:example:ebfeb1f712ebc6f1c276e12ec21/keys/1', typ: 'JWT' },
|
|
12
12
|
payload: { iss: 'sphereon:wallet', nonce: 'tZignsnFbp', jti: 'tZignsnFbp223', aud: IDENTIPROOF_ISSUER_URL, iat: Date.now() / 1000 },
|
|
13
13
|
};
|
|
14
14
|
|
|
15
15
|
const jwt_withoutDid: Jwt = {
|
|
16
|
-
header: { alg: Alg.ES256, kid: 'ebfeb1f712ebc6f1c276e12ec21/keys/1', typ: '
|
|
16
|
+
header: { alg: Alg.ES256, kid: 'ebfeb1f712ebc6f1c276e12ec21/keys/1', typ: 'JWT' },
|
|
17
17
|
payload: { iss: 'sphereon:wallet', nonce: 'tZignsnFbp', jti: 'tZignsnFbp223', aud: IDENTIPROOF_ISSUER_URL, iat: Date.now() / 1000 },
|
|
18
18
|
};
|
|
19
19
|
|
|
@@ -62,10 +62,10 @@ describe('ProofOfPossession Builder ', () => {
|
|
|
62
62
|
it('should fail without supplied proof or callbacks and with kid without did', async function () {
|
|
63
63
|
await expect(
|
|
64
64
|
ProofOfPossessionBuilder.fromProof(undefined as never, OpenId4VCIVersion.VER_1_0_13)
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
65
|
+
.withIssuer(IDENTIPROOF_ISSUER_URL)
|
|
66
|
+
.withClientId('sphereon:wallet')
|
|
67
|
+
.withKid(kid_withoutDid)
|
|
68
|
+
.build(),
|
|
69
69
|
).rejects.toThrow(Error(PROOF_CANT_BE_CONSTRUCTED));
|
|
70
70
|
});
|
|
71
71
|
|
|
@@ -87,11 +87,11 @@ describe('ProofOfPossession Builder ', () => {
|
|
|
87
87
|
callbacks: { signCallback: proofOfPossessionCallbackFunction },
|
|
88
88
|
version: OpenId4VCIVersion.VER_1_0_08,
|
|
89
89
|
})
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
90
|
+
.withJwt(undefined as never)
|
|
91
|
+
.withIssuer(IDENTIPROOF_ISSUER_URL)
|
|
92
|
+
.withClientId('sphereon:wallet')
|
|
93
|
+
.withKid(kid_withoutDid)
|
|
94
|
+
.build(),
|
|
95
95
|
).toThrow(Error(NO_JWT_PROVIDED));
|
|
96
96
|
});
|
|
97
97
|
|
|
@@ -118,10 +118,10 @@ describe('ProofOfPossession Builder ', () => {
|
|
|
118
118
|
},
|
|
119
119
|
version: OpenId4VCIVersion.VER_1_0_08,
|
|
120
120
|
})
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
121
|
+
.withIssuer(IDENTIPROOF_ISSUER_URL)
|
|
122
|
+
.withKid(kid_withoutDid)
|
|
123
|
+
.withClientId('sphereon:wallet')
|
|
124
|
+
.build();
|
|
125
125
|
expect(proof).toBeDefined();
|
|
126
126
|
});
|
|
127
127
|
|
|
@@ -152,10 +152,10 @@ describe('ProofOfPossession Builder ', () => {
|
|
|
152
152
|
callbacks: { signCallback: proofOfPossessionCallbackFunction },
|
|
153
153
|
version: OpenId4VCIVersion.VER_1_0_08,
|
|
154
154
|
})
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
155
|
+
.withIssuer(IDENTIPROOF_ISSUER_URL)
|
|
156
|
+
.withClientId('sphereon:wallet')
|
|
157
|
+
.withKid(kid_withoutDid)
|
|
158
|
+
.build(),
|
|
159
159
|
).rejects.toThrow(Error(JWS_NOT_VALID));
|
|
160
160
|
});
|
|
161
161
|
|
|
@@ -186,10 +186,10 @@ describe('ProofOfPossession Builder ', () => {
|
|
|
186
186
|
callbacks: { signCallback: proofOfPossessionCallbackFunction },
|
|
187
187
|
version: OpenId4VCIVersion.VER_1_0_08,
|
|
188
188
|
})
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
189
|
+
.withIssuer(IDENTIPROOF_ISSUER_URL)
|
|
190
|
+
.withClientId('sphereon:wallet')
|
|
191
|
+
.withKid(kid_withoutDid)
|
|
192
|
+
.build(),
|
|
193
193
|
).rejects.toThrow(Error(JWS_NOT_VALID));
|
|
194
194
|
});
|
|
195
195
|
});
|
|
@@ -215,37 +215,37 @@ describe('sd-jwt vc', () => {
|
|
|
215
215
|
const offered = supported['SdJwtCredentialId'] as CredentialSupportedSdJwtVc;
|
|
216
216
|
|
|
217
217
|
nock(issuerMetadata.token_endpoint as string)
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
218
|
+
.post('/')
|
|
219
|
+
.reply(200, async (_, body: string) => {
|
|
220
|
+
const parsedBody = Object.fromEntries(body.split('&').map((x) => x.split('=')));
|
|
221
|
+
return createAccessTokenResponse(parsedBody as AccessTokenRequest, {
|
|
222
|
+
credentialOfferSessions: vcIssuer.credentialOfferSessions,
|
|
223
|
+
accessTokenIssuer: 'https://issuer.example.com',
|
|
224
|
+
cNonces: vcIssuer.cNonces,
|
|
225
|
+
cNonce: 'a-c-nonce',
|
|
226
|
+
accessTokenSignerCallback: async () => 'ey.val.ue',
|
|
227
|
+
tokenExpiresIn: 500,
|
|
228
|
+
});
|
|
228
229
|
});
|
|
229
|
-
});
|
|
230
230
|
|
|
231
231
|
await client.acquireAccessToken({ pin: '123' });
|
|
232
232
|
nock(issuerMetadata.credential_endpoint as string)
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
233
|
+
.post('/')
|
|
234
|
+
.reply(200, async (_, body) =>
|
|
235
|
+
vcIssuer.issueCredential({
|
|
236
|
+
credentialRequest: { ...(body as CredentialRequestV1_0_13), credential_identifier: offered.vct },
|
|
237
|
+
credential: {
|
|
238
|
+
vct: 'Hello',
|
|
239
|
+
iss: 'example.com',
|
|
240
|
+
iat: 123,
|
|
241
|
+
// Defines what can be disclosed (optional)
|
|
242
|
+
__disclosureFrame: {
|
|
243
|
+
name: true,
|
|
244
|
+
},
|
|
244
245
|
},
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
);
|
|
246
|
+
newCNonce: 'new-c-nonce',
|
|
247
|
+
}),
|
|
248
|
+
);
|
|
249
249
|
|
|
250
250
|
const credentials = await client.acquireCredentials({
|
|
251
251
|
credentialIdentifier: offered.vct,
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { AccessTokenRequest, AccessTokenRequestOpts, Jwt, OpenId4VCIVersion } from '@sphereon/oid4vci-common';
|
|
2
|
+
import { v4 } from 'uuid';
|
|
3
|
+
|
|
4
|
+
import { ProofOfPossessionBuilder } from '../ProofOfPossessionBuilder';
|
|
5
|
+
|
|
6
|
+
export const createJwtBearerClientAssertion = async (
|
|
7
|
+
request: Partial<AccessTokenRequest>,
|
|
8
|
+
opts: AccessTokenRequestOpts & {
|
|
9
|
+
version?: OpenId4VCIVersion;
|
|
10
|
+
},
|
|
11
|
+
): Promise<void> => {
|
|
12
|
+
const { asOpts, credentialIssuer } = opts;
|
|
13
|
+
if (asOpts?.clientOpts?.clientAssertionType === 'urn:ietf:params:oauth:client-assertion-type:jwt-bearer') {
|
|
14
|
+
const { clientId = request.client_id, signCallbacks, alg } = asOpts.clientOpts;
|
|
15
|
+
let { kid } = asOpts.clientOpts;
|
|
16
|
+
if (!clientId) {
|
|
17
|
+
return Promise.reject(Error(`Not client_id supplied, but client-assertion jwt-bearer requested.`));
|
|
18
|
+
} else if (!kid) {
|
|
19
|
+
return Promise.reject(Error(`No kid supplied, but client-assertion jwt-bearer requested.`));
|
|
20
|
+
} else if (typeof signCallbacks?.signCallback !== 'function') {
|
|
21
|
+
return Promise.reject(Error(`No sign callback supplied, but client-assertion jwt-bearer requested.`));
|
|
22
|
+
} else if (!credentialIssuer) {
|
|
23
|
+
return Promise.reject(Error(`No credential issuer supplied, but client-assertion jwt-bearer requested.`));
|
|
24
|
+
}
|
|
25
|
+
if (clientId.startsWith('http') && kid.includes('#')) {
|
|
26
|
+
kid = kid.split('#')[1];
|
|
27
|
+
}
|
|
28
|
+
const jwt: Jwt = {
|
|
29
|
+
header: {
|
|
30
|
+
typ: 'JWT',
|
|
31
|
+
kid,
|
|
32
|
+
alg: alg ?? 'ES256',
|
|
33
|
+
},
|
|
34
|
+
payload: {
|
|
35
|
+
iss: clientId,
|
|
36
|
+
sub: clientId,
|
|
37
|
+
aud: credentialIssuer,
|
|
38
|
+
jti: v4(),
|
|
39
|
+
exp: Date.now() / 1000 + 60,
|
|
40
|
+
iat: Date.now() / 1000 - 60,
|
|
41
|
+
},
|
|
42
|
+
};
|
|
43
|
+
const pop = await ProofOfPossessionBuilder.fromJwt({
|
|
44
|
+
jwt,
|
|
45
|
+
callbacks: signCallbacks,
|
|
46
|
+
version: opts.version ?? OpenId4VCIVersion.VER_1_0_13,
|
|
47
|
+
mode: 'JWT',
|
|
48
|
+
}).build();
|
|
49
|
+
request.client_assertion_type = 'urn:ietf:params:oauth:client-assertion-type:jwt-bearer';
|
|
50
|
+
request.client_assertion = pop.jwt;
|
|
51
|
+
}
|
|
52
|
+
};
|
package/lib/functions/index.ts
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sphereon/oid4vci-client",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.13.0",
|
|
4
4
|
"description": "OpenID for Verifiable Credential Issuance (OpenID4VCI) client",
|
|
5
5
|
"source": "lib/index.ts",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -15,8 +15,8 @@
|
|
|
15
15
|
"build": "tsc"
|
|
16
16
|
},
|
|
17
17
|
"dependencies": {
|
|
18
|
-
"@sphereon/oid4vci-common": "0.
|
|
19
|
-
"@sphereon/ssi-types": "0.
|
|
18
|
+
"@sphereon/oid4vci-common": "0.13.0",
|
|
19
|
+
"@sphereon/ssi-types": "0.26.1-next.6",
|
|
20
20
|
"cross-fetch": "^3.1.8",
|
|
21
21
|
"debug": "^4.3.4"
|
|
22
22
|
},
|
|
@@ -69,5 +69,5 @@
|
|
|
69
69
|
"OIDC4VCI",
|
|
70
70
|
"OID4VCI"
|
|
71
71
|
],
|
|
72
|
-
"gitHead": "
|
|
72
|
+
"gitHead": "4ae9812531dfb8bd45809127a215cdc5d02c6d4f"
|
|
73
73
|
}
|