@sphereon/ssi-sdk.oid4vci-holder 0.34.1-next.88 → 0.36.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/index.cjs +417 -376
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +21 -12
- package/dist/index.d.ts +21 -12
- package/dist/index.js +417 -376
- package/dist/index.js.map +1 -1
- package/package.json +24 -24
- package/src/agent/OID4VCIHolder.ts +72 -48
- package/src/machines/firstPartyMachine.ts +1 -1
- package/src/machines/oid4vciMachine.ts +39 -6
- package/src/mappers/OIDC4VCIBrandingMapper.ts +1 -1
- package/src/services/OID4VCIHolderService.ts +42 -65
- package/src/types/FirstPartyMachine.ts +5 -5
- package/src/types/IOID4VCIHolder.ts +20 -12
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sphereon/ssi-sdk.oid4vci-holder",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.36.0",
|
|
4
4
|
"source": "src/index.ts",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.cjs",
|
|
@@ -26,27 +26,27 @@
|
|
|
26
26
|
"build": "tsup --config ../../tsup.config.ts --tsconfig ../../tsconfig.tsup.json"
|
|
27
27
|
},
|
|
28
28
|
"dependencies": {
|
|
29
|
-
"@sphereon/did-auth-siop": "0.
|
|
29
|
+
"@sphereon/did-auth-siop": "0.20.0",
|
|
30
30
|
"@sphereon/kmp-mdoc-core": "0.2.0-SNAPSHOT.26",
|
|
31
|
-
"@sphereon/oid4vci-client": "0.
|
|
32
|
-
"@sphereon/oid4vci-common": "0.
|
|
33
|
-
"@sphereon/ssi-sdk-ext.did-utils": "0.
|
|
34
|
-
"@sphereon/ssi-sdk-ext.identifier-resolution": "0.
|
|
35
|
-
"@sphereon/ssi-sdk-ext.jwt-service": "0.
|
|
36
|
-
"@sphereon/ssi-sdk-ext.key-utils": "0.
|
|
37
|
-
"@sphereon/ssi-sdk.contact-manager": "0.
|
|
38
|
-
"@sphereon/ssi-sdk.core": "0.
|
|
39
|
-
"@sphereon/ssi-sdk.credential-store": "0.
|
|
40
|
-
"@sphereon/ssi-sdk.credential-validation": "0.
|
|
41
|
-
"@sphereon/ssi-sdk.data-store": "0.
|
|
42
|
-
"@sphereon/ssi-sdk.issuance-branding": "0.
|
|
43
|
-
"@sphereon/ssi-sdk.mdl-mdoc": "0.
|
|
44
|
-
"@sphereon/ssi-sdk.oidf-client": "0.
|
|
45
|
-
"@sphereon/ssi-sdk.sd-jwt": "0.
|
|
46
|
-
"@sphereon/ssi-sdk.siopv2-oid4vp-common": "0.
|
|
47
|
-
"@sphereon/ssi-sdk.siopv2-oid4vp-op-auth": "0.
|
|
48
|
-
"@sphereon/ssi-sdk.xstate-machine-persistence": "0.
|
|
49
|
-
"@sphereon/ssi-types": "0.
|
|
31
|
+
"@sphereon/oid4vci-client": "0.20.0",
|
|
32
|
+
"@sphereon/oid4vci-common": "0.20.0",
|
|
33
|
+
"@sphereon/ssi-sdk-ext.did-utils": "0.36.0",
|
|
34
|
+
"@sphereon/ssi-sdk-ext.identifier-resolution": "0.36.0",
|
|
35
|
+
"@sphereon/ssi-sdk-ext.jwt-service": "0.36.0",
|
|
36
|
+
"@sphereon/ssi-sdk-ext.key-utils": "0.36.0",
|
|
37
|
+
"@sphereon/ssi-sdk.contact-manager": "0.36.0",
|
|
38
|
+
"@sphereon/ssi-sdk.core": "0.36.0",
|
|
39
|
+
"@sphereon/ssi-sdk.credential-store": "0.36.0",
|
|
40
|
+
"@sphereon/ssi-sdk.credential-validation": "0.36.0",
|
|
41
|
+
"@sphereon/ssi-sdk.data-store-types": "0.36.0",
|
|
42
|
+
"@sphereon/ssi-sdk.issuance-branding": "0.36.0",
|
|
43
|
+
"@sphereon/ssi-sdk.mdl-mdoc": "0.36.0",
|
|
44
|
+
"@sphereon/ssi-sdk.oidf-client": "0.36.0",
|
|
45
|
+
"@sphereon/ssi-sdk.sd-jwt": "0.36.0",
|
|
46
|
+
"@sphereon/ssi-sdk.siopv2-oid4vp-common": "0.36.0",
|
|
47
|
+
"@sphereon/ssi-sdk.siopv2-oid4vp-op-auth": "0.36.0",
|
|
48
|
+
"@sphereon/ssi-sdk.xstate-machine-persistence": "0.36.0",
|
|
49
|
+
"@sphereon/ssi-types": "0.36.0",
|
|
50
50
|
"@veramo/core": "4.2.0",
|
|
51
51
|
"@veramo/data-store": "4.2.0",
|
|
52
52
|
"@veramo/utils": "4.2.0",
|
|
@@ -59,8 +59,8 @@
|
|
|
59
59
|
"xstate": "^4.38.3"
|
|
60
60
|
},
|
|
61
61
|
"devDependencies": {
|
|
62
|
-
"@sphereon/oid4vc-common": "0.
|
|
63
|
-
"@sphereon/ssi-sdk-ext.did-resolver-jwk": "0.
|
|
62
|
+
"@sphereon/oid4vc-common": "0.20.0",
|
|
63
|
+
"@sphereon/ssi-sdk-ext.did-resolver-jwk": "0.36.0",
|
|
64
64
|
"@sphereon/ssi-sdk.siopv2-oid4vp-common": "workspace:*",
|
|
65
65
|
"@types/i18n-js": "^3.8.9",
|
|
66
66
|
"@types/lodash.memoize": "^4.1.9",
|
|
@@ -90,5 +90,5 @@
|
|
|
90
90
|
"OID4VCI",
|
|
91
91
|
"State Machine"
|
|
92
92
|
],
|
|
93
|
-
"gitHead": "
|
|
93
|
+
"gitHead": "f713d3a83948ef69aaa7d435700b16d5655ac863"
|
|
94
94
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { CredentialOfferClient, MetadataClient, OpenID4VCIClient } from '@sphereon/oid4vci-client'
|
|
1
|
+
import { CredentialOfferClient, MetadataClient, OpenID4VCIClient, OpenID4VCIClientV1_0_15 } from '@sphereon/oid4vci-client'
|
|
2
2
|
import {
|
|
3
|
-
|
|
3
|
+
AuthorizationDetailsV1_0_15,
|
|
4
4
|
AuthorizationRequestOpts,
|
|
5
5
|
AuthorizationServerClientOpts,
|
|
6
6
|
AuthorizationServerOpts,
|
|
@@ -9,8 +9,6 @@ import {
|
|
|
9
9
|
CredentialOfferRequestWithBaseUrl,
|
|
10
10
|
DefaultURISchemes,
|
|
11
11
|
EndpointMetadataResult,
|
|
12
|
-
getTypesFromAuthorizationDetails,
|
|
13
|
-
getTypesFromCredentialOffer,
|
|
14
12
|
getTypesFromObject,
|
|
15
13
|
Jwt,
|
|
16
14
|
NotificationRequest,
|
|
@@ -35,7 +33,6 @@ import {
|
|
|
35
33
|
ConnectionType,
|
|
36
34
|
CorrelationIdentifierType,
|
|
37
35
|
CredentialCorrelationType,
|
|
38
|
-
CredentialRole,
|
|
39
36
|
ensureRawDocument,
|
|
40
37
|
FindPartyArgs,
|
|
41
38
|
IBasicCredentialLocaleBranding,
|
|
@@ -45,17 +42,17 @@ import {
|
|
|
45
42
|
IIssuerLocaleBranding,
|
|
46
43
|
NonPersistedIdentity,
|
|
47
44
|
Party,
|
|
48
|
-
} from '@sphereon/ssi-sdk.data-store'
|
|
45
|
+
} from '@sphereon/ssi-sdk.data-store-types'
|
|
49
46
|
import {
|
|
50
47
|
CredentialMapper,
|
|
51
48
|
type CredentialProofFormat,
|
|
49
|
+
CredentialRole,
|
|
52
50
|
HasherSync,
|
|
53
51
|
IVerifiableCredential,
|
|
54
52
|
JoseSignatureAlgorithm,
|
|
55
53
|
JoseSignatureAlgorithmString,
|
|
56
54
|
JwtDecodedVerifiableCredential,
|
|
57
55
|
Loggers,
|
|
58
|
-
OriginalVerifiableCredential,
|
|
59
56
|
parseDid,
|
|
60
57
|
SdJwtDecodedVerifiableCredentialPayload,
|
|
61
58
|
WrappedW3CVerifiableCredential,
|
|
@@ -71,10 +68,12 @@ import {
|
|
|
71
68
|
W3CVerifiableCredential,
|
|
72
69
|
} from '@veramo/core'
|
|
73
70
|
import { asArray, computeEntryHash } from '@veramo/utils'
|
|
71
|
+
import fetch from 'cross-fetch'
|
|
74
72
|
import { decodeJWT } from 'did-jwt'
|
|
75
73
|
import { v4 as uuidv4 } from 'uuid'
|
|
76
74
|
import { OID4VCIMachine } from '../machines/oid4vciMachine'
|
|
77
75
|
import {
|
|
76
|
+
extractCredentialFromResponse,
|
|
78
77
|
getBasicIssuerLocaleBranding,
|
|
79
78
|
getCredentialBranding,
|
|
80
79
|
getCredentialConfigsSupportedMerged,
|
|
@@ -85,7 +84,6 @@ import {
|
|
|
85
84
|
startFirstPartApplicationMachine,
|
|
86
85
|
verifyCredentialToAccept,
|
|
87
86
|
} from '../services/OID4VCIHolderService'
|
|
88
|
-
import 'cross-fetch/polyfill'
|
|
89
87
|
import {
|
|
90
88
|
AddContactIdentityArgs,
|
|
91
89
|
AssertValidCredentialsArgs,
|
|
@@ -111,6 +109,8 @@ import {
|
|
|
111
109
|
OnContactIdentityCreatedArgs,
|
|
112
110
|
OnCredentialStoredArgs,
|
|
113
111
|
OnIdentifierCreatedArgs,
|
|
112
|
+
PrepareAuthorizationRequestArgs,
|
|
113
|
+
PrepareAuthorizationResult,
|
|
114
114
|
PrepareStartArgs,
|
|
115
115
|
RequestType,
|
|
116
116
|
RequiredContext,
|
|
@@ -216,6 +216,7 @@ export class OID4VCIHolder implements IAgentPlugin {
|
|
|
216
216
|
oid4vciHolderStart: this.oid4vciHolderStart.bind(this),
|
|
217
217
|
oid4vciHolderGetIssuerMetadata: this.oid4vciHolderGetIssuerMetadata.bind(this),
|
|
218
218
|
oid4vciHolderGetMachineInterpreter: this.oid4vciHolderGetMachineInterpreter.bind(this),
|
|
219
|
+
oid4vciHolderPrepareAuthorizationRequest: this.oid4vciHolderPrepareAuthorizationRequest.bind(this),
|
|
219
220
|
oid4vciHolderCreateCredentialsToSelectFrom: this.oid4vciHolderCreateCredentialsToSelectFrom.bind(this),
|
|
220
221
|
oid4vciHolderGetContact: this.oid4vciHolderGetContact.bind(this),
|
|
221
222
|
oid4vciHolderGetCredentials: this.oid4vciHolderGetCredentials.bind(this),
|
|
@@ -229,7 +230,7 @@ export class OID4VCIHolder implements IAgentPlugin {
|
|
|
229
230
|
oid4vciHolderStoreIssuerBranding: this.oid4vciHolderStoreIssuerBranding.bind(this),
|
|
230
231
|
}
|
|
231
232
|
|
|
232
|
-
private readonly vcFormatPreferences: Array<string> = ['dc+sd-jwt', 'vc+sd-jwt', 'mso_mdoc', 'jwt_vc_json', 'jwt_vc', 'ldp_vc']
|
|
233
|
+
private readonly vcFormatPreferences: Array<string> = ['dc+sd-jwt', 'vc+sd-jwt', 'mso_mdoc', 'jwt_vc_json', 'jwt_vc', 'ldp_vc'] // TODO see SSISDK-52 concerning vc+sd-jwt
|
|
233
234
|
private readonly jsonldCryptographicSuitePreferences: Array<string> = [
|
|
234
235
|
'Ed25519Signature2018',
|
|
235
236
|
'EcdsaSecp256k1Signature2019',
|
|
@@ -326,6 +327,8 @@ export class OID4VCIHolder implements IAgentPlugin {
|
|
|
326
327
|
startFirstPartApplicationMachine({ ...args, stateNavigationListener: opts.firstPartyStateNavigationListener }, context),
|
|
327
328
|
[OID4VCIMachineServices.createCredentialsToSelectFrom]: (args: CreateCredentialsToSelectFromArgs) =>
|
|
328
329
|
this.oid4vciHolderCreateCredentialsToSelectFrom(args, context),
|
|
330
|
+
[OID4VCIMachineServices.prepareAuthorizationRequest]: (args: PrepareAuthorizationRequestArgs) =>
|
|
331
|
+
this.oid4vciHolderPrepareAuthorizationRequest(args, context),
|
|
329
332
|
[OID4VCIMachineServices.getContact]: (args: GetContactArgs) => this.oid4vciHolderGetContact(args, context),
|
|
330
333
|
[OID4VCIMachineServices.getCredentials]: (args: GetCredentialsArgs) =>
|
|
331
334
|
this.oid4vciHolderGetCredentials({ accessTokenOpts: args.accessTokenOpts ?? opts.accessTokenOpts, ...args }, context),
|
|
@@ -375,11 +378,9 @@ export class OID4VCIHolder implements IAgentPlugin {
|
|
|
375
378
|
}
|
|
376
379
|
|
|
377
380
|
const authorizationRequestOpts = { ...this.defaultAuthorizationRequestOpts, ...args.authorizationRequestOpts } satisfies AuthorizationRequestOpts
|
|
378
|
-
//
|
|
381
|
+
// TODO: Previously we filtered the details first against our vcformat prefs. However auth details does not have the notion of formats anymore
|
|
379
382
|
authorizationRequestOpts.authorizationDetails = authorizationRequestOpts?.authorizationDetails
|
|
380
|
-
? asArray(authorizationRequestOpts.authorizationDetails)
|
|
381
|
-
(detail) => typeof detail === 'string' || this.vcFormatPreferences.includes(detail.format),
|
|
382
|
-
)
|
|
383
|
+
? asArray(authorizationRequestOpts.authorizationDetails)
|
|
383
384
|
: undefined
|
|
384
385
|
|
|
385
386
|
if (!authorizationRequestOpts.redirectUri) {
|
|
@@ -391,19 +392,19 @@ export class OID4VCIHolder implements IAgentPlugin {
|
|
|
391
392
|
authorizationRequestOpts.clientId = authorizationRequestOpts.redirectUri
|
|
392
393
|
}
|
|
393
394
|
|
|
395
|
+
// TODO: This entire filter and formats population should not work anymore, as the auth details no longer have the format property.
|
|
394
396
|
let formats: string[] = this.vcFormatPreferences
|
|
395
397
|
const authFormats = authorizationRequestOpts?.authorizationDetails
|
|
396
|
-
?.map((detail:
|
|
398
|
+
?.map((detail: AuthorizationDetailsV1_0_15) => (typeof detail === 'object' && 'format' in detail && detail.format ? detail.format : undefined))
|
|
397
399
|
.filter((format) => !!format)
|
|
398
400
|
.map((format) => format as string)
|
|
399
401
|
if (authFormats && authFormats.length > 0) {
|
|
400
402
|
formats = Array.from(new Set(authFormats))
|
|
401
403
|
}
|
|
402
|
-
let oid4vciClient:
|
|
403
|
-
let types: string[][] | undefined = undefined
|
|
404
|
+
let oid4vciClient: OpenID4VCIClientV1_0_15
|
|
404
405
|
let offer: CredentialOfferRequestWithBaseUrl | undefined
|
|
405
406
|
if (requestData.existingClientState) {
|
|
406
|
-
oid4vciClient = await
|
|
407
|
+
oid4vciClient = await OpenID4VCIClientV1_0_15.fromState({ state: requestData.existingClientState })
|
|
407
408
|
offer = oid4vciClient.credentialOffer
|
|
408
409
|
} else {
|
|
409
410
|
offer = requestData.credentialOffer
|
|
@@ -425,46 +426,44 @@ export class OID4VCIHolder implements IAgentPlugin {
|
|
|
425
426
|
if (!offer) {
|
|
426
427
|
// else no offer, meaning we have an issuer URL
|
|
427
428
|
logger.log(`Issuer url received (no credential offer): ${uri}`)
|
|
428
|
-
oid4vciClient = await
|
|
429
|
+
oid4vciClient = await OpenID4VCIClientV1_0_15.fromCredentialIssuer({
|
|
429
430
|
credentialIssuer: uri,
|
|
430
431
|
authorizationRequest: authorizationRequestOpts,
|
|
431
432
|
clientId: authorizationRequestOpts.clientId,
|
|
432
|
-
createAuthorizationRequestURL: requestData.createAuthorizationRequestURL ?? true,
|
|
433
|
+
createAuthorizationRequestURL: false, // requestData.createAuthorizationRequestURL ?? true,
|
|
433
434
|
})
|
|
434
435
|
} else {
|
|
435
436
|
logger.log(`Credential offer received: ${uri}`)
|
|
436
|
-
oid4vciClient = await
|
|
437
|
+
oid4vciClient = await OpenID4VCIClientV1_0_15.fromURI({
|
|
437
438
|
uri,
|
|
438
439
|
authorizationRequest: authorizationRequestOpts,
|
|
439
440
|
clientId: authorizationRequestOpts.clientId,
|
|
440
|
-
createAuthorizationRequestURL: requestData.createAuthorizationRequestURL ?? true,
|
|
441
|
+
createAuthorizationRequestURL: false, // requestData.createAuthorizationRequestURL ?? true,
|
|
441
442
|
})
|
|
442
443
|
}
|
|
443
444
|
}
|
|
444
445
|
|
|
446
|
+
let configurationIds: Array<string> = []
|
|
445
447
|
if (offer) {
|
|
446
|
-
|
|
448
|
+
configurationIds = offer.original_credential_offer.credential_configuration_ids
|
|
447
449
|
} else {
|
|
448
|
-
|
|
449
|
-
.
|
|
450
|
-
.
|
|
450
|
+
configurationIds = asArray(authorizationRequestOpts.authorizationDetails)
|
|
451
|
+
// .filter((authDetails): authDetails is Exclude<AuthorizationDetailsV1_0_15, string> => typeof authDetails !== 'string')
|
|
452
|
+
.map((authReqOpts) => authReqOpts.credential_configuration_id)
|
|
453
|
+
.filter((id): id is string => !!id)
|
|
451
454
|
}
|
|
452
455
|
|
|
453
|
-
const serverMetadata = await oid4vciClient.retrieveServerMetadata()
|
|
454
456
|
const credentialsSupported = await getCredentialConfigsSupportedMerged({
|
|
455
457
|
client: oid4vciClient,
|
|
456
458
|
vcFormatPreferences: formats,
|
|
457
|
-
|
|
459
|
+
configurationIds,
|
|
458
460
|
})
|
|
461
|
+
|
|
462
|
+
const serverMetadata = await oid4vciClient.retrieveServerMetadata()
|
|
459
463
|
const credentialBranding = await getCredentialBranding({ credentialsSupported, context })
|
|
460
|
-
const authorizationCodeURL = oid4vciClient.authorizationURL
|
|
461
|
-
if (authorizationCodeURL) {
|
|
462
|
-
logger.log(`authorization code URL ${authorizationCodeURL}`)
|
|
463
|
-
}
|
|
464
464
|
const oid4vciClientState = JSON.parse(await oid4vciClient.exportState())
|
|
465
465
|
|
|
466
466
|
return {
|
|
467
|
-
authorizationCodeURL,
|
|
468
467
|
credentialBranding,
|
|
469
468
|
credentialsSupported,
|
|
470
469
|
serverMetadata,
|
|
@@ -472,6 +471,44 @@ export class OID4VCIHolder implements IAgentPlugin {
|
|
|
472
471
|
}
|
|
473
472
|
}
|
|
474
473
|
|
|
474
|
+
private async oid4vciHolderPrepareAuthorizationRequest(
|
|
475
|
+
args: PrepareAuthorizationRequestArgs,
|
|
476
|
+
context: RequiredContext,
|
|
477
|
+
): Promise<PrepareAuthorizationResult> {
|
|
478
|
+
const { openID4VCIClientState, contact } = args
|
|
479
|
+
if (!openID4VCIClientState) {
|
|
480
|
+
return Promise.reject(Error('Missing openID4VCI client state in context'))
|
|
481
|
+
}
|
|
482
|
+
|
|
483
|
+
const clientId = contact?.identities
|
|
484
|
+
.map((identity) => {
|
|
485
|
+
const connectionConfig = identity.connection?.config
|
|
486
|
+
if (connectionConfig && 'clientId' in connectionConfig) {
|
|
487
|
+
return connectionConfig.clientId
|
|
488
|
+
}
|
|
489
|
+
return undefined
|
|
490
|
+
})
|
|
491
|
+
.find((clientId) => clientId)
|
|
492
|
+
|
|
493
|
+
if (!clientId) {
|
|
494
|
+
return Promise.reject(Error(`Missing client id in contact's connectionConfig`))
|
|
495
|
+
}
|
|
496
|
+
const client = await OpenID4VCIClient.fromState({ state: openID4VCIClientState })
|
|
497
|
+
const authorizationCodeURL = await client.createAuthorizationRequestUrl({
|
|
498
|
+
authorizationRequest: {
|
|
499
|
+
clientId: clientId,
|
|
500
|
+
} satisfies AuthorizationRequestOpts,
|
|
501
|
+
})
|
|
502
|
+
if (authorizationCodeURL) {
|
|
503
|
+
logger.log(`authorization code URL ${authorizationCodeURL}`)
|
|
504
|
+
}
|
|
505
|
+
return {
|
|
506
|
+
authorizationCodeURL,
|
|
507
|
+
// Needed, because the above createAuthorizationRequestUrl manipulates the state, adding pkce opts to the state
|
|
508
|
+
oid4vciClientState: JSON.parse(await client.exportState())
|
|
509
|
+
}
|
|
510
|
+
}
|
|
511
|
+
|
|
475
512
|
private async oid4vciHolderCreateCredentialsToSelectFrom(
|
|
476
513
|
args: CreateCredentialsToSelectFromArgs,
|
|
477
514
|
context: RequiredContext,
|
|
@@ -587,7 +624,7 @@ export class OID4VCIHolder implements IAgentPlugin {
|
|
|
587
624
|
return Promise.reject(Error('Missing openID4VCI client state in context'))
|
|
588
625
|
}
|
|
589
626
|
|
|
590
|
-
const client = await
|
|
627
|
+
const client = await OpenID4VCIClientV1_0_15.fromState({ state: openID4VCIClientState })
|
|
591
628
|
const credentialsSupported = await getCredentialConfigsSupportedMerged({
|
|
592
629
|
client,
|
|
593
630
|
vcFormatPreferences: this.vcFormatPreferences,
|
|
@@ -939,21 +976,8 @@ export class OID4VCIHolder implements IAgentPlugin {
|
|
|
939
976
|
? 'credential_accepted_holder_signed'
|
|
940
977
|
: 'credential_deleted_holder_signed'
|
|
941
978
|
logger.log(`Subject issuance/signing will be used, with event`, event)
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
if ('credential' in credentialResponse) {
|
|
945
|
-
issuerVC = credentialResponse.credential as OriginalVerifiableCredential
|
|
946
|
-
} else if (
|
|
947
|
-
'credentials' in credentialResponse &&
|
|
948
|
-
credentialResponse.credentials &&
|
|
949
|
-
Array.isArray(credentialResponse.credentials) &&
|
|
950
|
-
credentialResponse.credentials.length > 0
|
|
951
|
-
) {
|
|
952
|
-
issuerVC = credentialResponse.credentials[0].credential as OriginalVerifiableCredential // FIXME SSISDK-13 (no multi-credential support yet)
|
|
953
|
-
}
|
|
954
|
-
if (!issuerVC) {
|
|
955
|
-
return Promise.reject(Error('No credential found in credential response'))
|
|
956
|
-
}
|
|
979
|
+
|
|
980
|
+
const issuerVC = extractCredentialFromResponse(mappedCredentialToAccept.credentialToAccept.credentialResponse)
|
|
957
981
|
const wrappedIssuerVC = CredentialMapper.toWrappedVerifiableCredential(issuerVC, { hasher: this.hasher ?? defaultHasher })
|
|
958
982
|
console.log(`Wrapped VC: ${wrappedIssuerVC.type}, ${wrappedIssuerVC.format}`)
|
|
959
983
|
// We will use the subject of the VCI Issuer (the holder, as the issuer of the new credential, so the below is not a mistake!)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { assign, createMachine, DoneInvokeEvent, interpret } from 'xstate'
|
|
2
2
|
import { AuthorizationChallengeCodeResponse, AuthorizationChallengeError, AuthorizationChallengeErrorResponse } from '@sphereon/oid4vci-common'
|
|
3
|
-
import { DidAuthConfig } from '@sphereon/ssi-sdk.data-store'
|
|
3
|
+
import { DidAuthConfig } from '@sphereon/ssi-sdk.data-store-types'
|
|
4
4
|
import { CreateConfigResult } from '@sphereon/ssi-sdk.siopv2-oid4vp-op-auth'
|
|
5
5
|
import { createConfig, getSiopRequest, sendAuthorizationChallengeRequest, sendAuthorizationResponse } from '../services/FirstPartyMachineServices'
|
|
6
6
|
import { translate } from '../localization/Localization'
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { AuthorizationChallengeCodeResponse, AuthzFlowType, toAuthorizationResponsePayload } from '@sphereon/oid4vci-common'
|
|
2
|
-
import { IBasicIssuerLocaleBranding, Identity, IIssuerLocaleBranding, Party } from '@sphereon/ssi-sdk.data-store'
|
|
2
|
+
import { IBasicIssuerLocaleBranding, Identity, IIssuerLocaleBranding, Party } from '@sphereon/ssi-sdk.data-store-types'
|
|
3
3
|
import { assign, createMachine, DoneInvokeEvent, interpret } from 'xstate'
|
|
4
4
|
import { translate } from '../localization/Localization'
|
|
5
5
|
import {
|
|
@@ -28,6 +28,7 @@ import {
|
|
|
28
28
|
SelectCredentialsEvent,
|
|
29
29
|
SetAuthorizationCodeURLEvent,
|
|
30
30
|
VerificationCodeEvent,
|
|
31
|
+
PrepareAuthorizationResult,
|
|
31
32
|
} from '../types/IOID4VCIHolder'
|
|
32
33
|
import { FirstPartyMachineStateTypes } from '../types/FirstPartyMachine'
|
|
33
34
|
|
|
@@ -98,9 +99,7 @@ const oid4vciRequireAuthorizationGuard = (ctx: OID4VCIMachineContext, _event: OI
|
|
|
98
99
|
throw Error('Missing openID4VCI client state in context')
|
|
99
100
|
}
|
|
100
101
|
|
|
101
|
-
if (
|
|
102
|
-
return false
|
|
103
|
-
} else if (openID4VCIClientState.authorizationRequestOpts) {
|
|
102
|
+
if (openID4VCIClientState.authorizationURL && openID4VCIClientState.authorizationRequestOpts) {
|
|
104
103
|
// We have authz options or there is not credential offer to begin with.
|
|
105
104
|
// We require authz as long as we do not have the authz code response
|
|
106
105
|
return !ctx.openID4VCIClientState?.authorizationCodeResponse
|
|
@@ -164,6 +163,9 @@ const createOID4VCIMachine = (opts?: CreateOID4VCIMachineOpts): OID4VCIStateMach
|
|
|
164
163
|
[OID4VCIMachineServices.start]: {
|
|
165
164
|
data: StartResult
|
|
166
165
|
}
|
|
166
|
+
[OID4VCIMachineServices.prepareAuthorizationRequest]: {
|
|
167
|
+
data: PrepareAuthorizationResult
|
|
168
|
+
}
|
|
167
169
|
[OID4VCIMachineServices.createCredentialsToSelectFrom]: {
|
|
168
170
|
data: Array<CredentialToSelectFromResult>
|
|
169
171
|
}
|
|
@@ -208,7 +210,6 @@ const createOID4VCIMachine = (opts?: CreateOID4VCIMachineOpts): OID4VCIStateMach
|
|
|
208
210
|
onDone: {
|
|
209
211
|
target: OID4VCIMachineStates.createCredentialsToSelectFrom,
|
|
210
212
|
actions: assign({
|
|
211
|
-
authorizationCodeURL: (_ctx: OID4VCIMachineContext, _event: DoneInvokeEvent<StartResult>) => _event.data.authorizationCodeURL,
|
|
212
213
|
credentialBranding: (_ctx: OID4VCIMachineContext, _event: DoneInvokeEvent<StartResult>) => _event.data.credentialBranding ?? {},
|
|
213
214
|
credentialsSupported: (_ctx: OID4VCIMachineContext, _event: DoneInvokeEvent<StartResult>) => _event.data.credentialsSupported,
|
|
214
215
|
serverMetadata: (_ctx: OID4VCIMachineContext, _event: DoneInvokeEvent<StartResult>) => _event.data.serverMetadata,
|
|
@@ -439,6 +440,10 @@ const createOID4VCIMachine = (opts?: CreateOID4VCIMachineOpts): OID4VCIStateMach
|
|
|
439
440
|
target: OID4VCIMachineStates.startFirstPartApplicationFlow,
|
|
440
441
|
cond: OID4VCIMachineGuards.isFirstPartyApplication,
|
|
441
442
|
},
|
|
443
|
+
{
|
|
444
|
+
target: OID4VCIMachineStates.prepareAuthorizationRequest,
|
|
445
|
+
cond: OID4VCIMachineGuards.requireAuthorizationGuard,
|
|
446
|
+
},
|
|
442
447
|
{
|
|
443
448
|
target: OID4VCIMachineStates.initiateAuthorizationRequest,
|
|
444
449
|
cond: OID4VCIMachineGuards.requireAuthorizationGuard,
|
|
@@ -511,12 +516,16 @@ const createOID4VCIMachine = (opts?: CreateOID4VCIMachineOpts): OID4VCIStateMach
|
|
|
511
516
|
target: OID4VCIMachineStates.startFirstPartApplicationFlow,
|
|
512
517
|
cond: OID4VCIMachineGuards.isFirstPartyApplication,
|
|
513
518
|
},
|
|
519
|
+
{
|
|
520
|
+
target: OID4VCIMachineStates.prepareAuthorizationRequest,
|
|
521
|
+
cond: OID4VCIMachineGuards.requireAuthorizationGuard,
|
|
522
|
+
},
|
|
514
523
|
{
|
|
515
524
|
target: OID4VCIMachineStates.verifyPin,
|
|
516
525
|
cond: OID4VCIMachineGuards.requirePinGuard,
|
|
517
526
|
},
|
|
518
527
|
{
|
|
519
|
-
target: OID4VCIMachineStates.
|
|
528
|
+
target: OID4VCIMachineStates.prepareAuthorizationRequest,
|
|
520
529
|
cond: OID4VCIMachineGuards.requireAuthorizationGuard,
|
|
521
530
|
},
|
|
522
531
|
{
|
|
@@ -524,6 +533,30 @@ const createOID4VCIMachine = (opts?: CreateOID4VCIMachineOpts): OID4VCIStateMach
|
|
|
524
533
|
},
|
|
525
534
|
],
|
|
526
535
|
},
|
|
536
|
+
[OID4VCIMachineStates.prepareAuthorizationRequest]: {
|
|
537
|
+
id: OID4VCIMachineStates.prepareAuthorizationRequest,
|
|
538
|
+
invoke: {
|
|
539
|
+
src: OID4VCIMachineServices.prepareAuthorizationRequest,
|
|
540
|
+
onDone: {
|
|
541
|
+
target: OID4VCIMachineStates.initiateAuthorizationRequest,
|
|
542
|
+
actions: assign({
|
|
543
|
+
authorizationCodeURL: (_ctx: OID4VCIMachineContext, _event: DoneInvokeEvent<PrepareAuthorizationResult>) =>
|
|
544
|
+
_event.data.authorizationCodeURL,
|
|
545
|
+
openID4VCIClientState: (_ctx: OID4VCIMachineContext, _event: DoneInvokeEvent<PrepareAuthorizationResult>) => _event.data.oid4vciClientState,
|
|
546
|
+
}),
|
|
547
|
+
},
|
|
548
|
+
onError: {
|
|
549
|
+
target: OID4VCIMachineStates.handleError,
|
|
550
|
+
actions: assign({
|
|
551
|
+
error: (_ctx: OID4VCIMachineContext, _event: DoneInvokeEvent<Error>): ErrorDetails => ({
|
|
552
|
+
title: translate('oid4vci_machine_prepare_authorization_error_title'),
|
|
553
|
+
message: _event.data.message,
|
|
554
|
+
stack: _event.data.stack,
|
|
555
|
+
}),
|
|
556
|
+
}),
|
|
557
|
+
},
|
|
558
|
+
},
|
|
559
|
+
},
|
|
527
560
|
[OID4VCIMachineStates.initiateAuthorizationRequest]: {
|
|
528
561
|
id: OID4VCIMachineStates.initiateAuthorizationRequest,
|
|
529
562
|
on: {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { CredentialsSupportedDisplay, NameAndLocale } from '@sphereon/oid4vci-common'
|
|
2
|
-
import { IBasicCredentialClaim, IBasicCredentialLocaleBranding, IBasicIssuerLocaleBranding } from '@sphereon/ssi-sdk.data-store'
|
|
2
|
+
import { IBasicCredentialClaim, IBasicCredentialLocaleBranding, IBasicIssuerLocaleBranding } from '@sphereon/ssi-sdk.data-store-types'
|
|
3
3
|
import { SdJwtClaimDisplayMetadata, SdJwtClaimMetadata, SdJwtClaimPath, SdJwtTypeDisplayMetadata } from '@sphereon/ssi-types'
|
|
4
4
|
import {
|
|
5
5
|
IssuerLocaleBrandingFromArgs,
|