diff --git a/packages/oid4vci-holder/README.md b/packages/oid4vci-holder/README.md index 1eed2108c..637166b57 100644 --- a/packages/oid4vci-holder/README.md +++ b/packages/oid4vci-holder/README.md @@ -12,7 +12,53 @@ --- -TODO +## Usage + +### OPENID_INITIATE_ISSUANCE SCHEMA + +pre-authorized_code + +```typescript +agent.oid4vciHolderGetInitiationData({ + requestData: { + uri: 'openid-initiate-issuance://?issuer=https%3A%2F%2Fissuer.research.identiproof.io&credential_type=OpenBadgeCredentialUrl&pre-authorized_code=4jLs9xZHEfqcoow0kHE7d1a8hUk6Sy-5bVSV2MqBUGUgiFFQi-ImL62T-FmLIo8hKA1UdMPH0lM1xAgcFkJfxIw9L-lI3mVs0hRT8YVwsEM1ma6N3wzuCdwtMU4bcwKp&user_pin_required=true' + } +}) +``` + +### OPENID_CREDENTIAL_OFFER SCHEMA + +pre-authorized_code + +```typescript +agent.oid4vciHolderGetInitiationData({ + requestData: { + uri: 'openid-credential-offer://?credential_offer%3D%7B%22credential_issuer%22%3A%22https%3A%2F%2Fissuer.research.identiproof.io%22%2C%22credentials%22%3A%5B%7B%22format%22%3A%22jwt_vc_json%22%2C%22types%22%3A%5B%22VerifiableCredential%22%2C%22UniversityDegreeCredential%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%22adhjhdjajkdkhjhdj%22%2C%22user_pin_required%22%3Atrue%7D%7D%7D' + } +}) +``` + +### HTTPS SCHEMA + +authorization_code: + +```typescript +agent.oid4vciHolderGetInitiationData({ + requestData: { + uri: 'https://issuer.research.identiproof.io?credential_offer%3D%7B%22credential_issuer%22%3A%22https%3A%2F%2Fissuer.research.identiproof.io%22%2C%22credentials%22%3A%5B%7B%22format%22%3A%22jwt_vc_json%22%2C%22types%22%3A%5B%22VerifiableCredential%22%2C%22UniversityDegreeCredential%22%5D%7D%5D%2C%22grants%22%3A%7B%22authorization_code%22%3A%7B%22issuer_state%22%3A%22eyJhbGciOiJSU0Et...FYUaBy%22%7D%7D%7D' + } +}) +``` + +pre-authorized_code: + +```typescript +agent.oid4vciHolderGetInitiationData({ + requestData: { + uri: 'https://issuer.research.identiproof.io?credential_offer%3D%7B%22credential_issuer%22%3A%22https%3A%2F%2Fissuer.research.identiproof.io%22%2C%22credentials%22%3A%5B%7B%22format%22%3A%22jwt_vc_json%22%2C%22types%22%3A%5B%22VerifiableCredential%22%2C%22UniversityDegreeCredential%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%22adhjhdjajkdkhjhdj%22%2C%22user_pin_required%22%3Atrue%7D%7D%7D' + } +}) +``` ## Installation diff --git a/packages/oid4vci-holder/__tests__/localAgent.test.ts b/packages/oid4vci-holder/__tests__/localAgent.test.ts index a61a3cd8b..74ce488e0 100644 --- a/packages/oid4vci-holder/__tests__/localAgent.test.ts +++ b/packages/oid4vci-holder/__tests__/localAgent.test.ts @@ -3,14 +3,14 @@ import { createObjects, getConfig } from '../../agent-config/dist' jest.setTimeout(60000) -import eventLoggerAgentLogic from './shared/eventLoggerAgentLogic' +import eventLoggerAgentLogic from './shared/oid4vciHolderLogicAgentLogic' let dbConnection: Promise let agent: any const setup = async (): Promise => { - const config = await getConfig('packages/event-logger/agent.yml') - const { localAgent, db } = await createObjects(config, { localAgent: '/agent', db: '/dbConnection' }) + const config = await getConfig('packages/oid4vci-holder/agent.yml') + const { localAgent, db } = await createObjects(config, { localAgent: '/agent' }) agent = localAgent dbConnection = db diff --git a/packages/oid4vci-holder/__tests__/restAgent.test.ts b/packages/oid4vci-holder/__tests__/restAgent.test.ts index d0851372b..e199d5419 100644 --- a/packages/oid4vci-holder/__tests__/restAgent.test.ts +++ b/packages/oid4vci-holder/__tests__/restAgent.test.ts @@ -7,7 +7,7 @@ import { IAgent, createAgent, IAgentOptions } from '@veramo/core' import { AgentRestClient } from '@veramo/remote-client' import { AgentRouter, RequestWithAgentRouter } from '@veramo/remote-server' import { createObjects, getConfig } from '../../agent-config/dist' -import eventLoggerAgentLogic from './shared/eventLoggerAgentLogic' +import eventLoggerAgentLogic from './shared/oid4vciHolderLogicAgentLogic' import { IOID4VCIHolder } from '../src' jest.setTimeout(60000) @@ -32,7 +32,7 @@ const getAgent = (options?: IAgentOptions) => }) const setup = async (): Promise => { - const config = await getConfig('packages/event-logger/agent.yml') + const config = await getConfig('packages/oid4vci-holder/agent.yml') const { agent, db } = await createObjects(config, { agent: '/agent', db: '/dbConnection' }) serverAgent = agent dbConnection = db diff --git a/packages/oid4vci-holder/__tests__/shared/MetadataMocks.ts b/packages/oid4vci-holder/__tests__/shared/MetadataMocks.ts new file mode 100644 index 000000000..c99a31bb8 --- /dev/null +++ b/packages/oid4vci-holder/__tests__/shared/MetadataMocks.ts @@ -0,0 +1,1353 @@ +export const GET_INITIATION_DATA_PRE_AUTHORIZED_HTTPS_INITIATE_FLOW = { + "credentialBranding": {}, + "credentialsSupported": [], + "openID4VCIClientState": { + "authorizationRequestOpts": { + "redirectUri": "openid-credential-offer://" + }, + "credentialIssuer": "https://issuer.research.identiproof.io", + "credentialOffer": { + "baseUrl": "https://issuer.research.identiproof.io", + "credential_offer": { + "credential_issuer": "https://issuer.research.identiproof.io", + "credentials": [ + "OpenBadgeCredentialUrl", + "VerifiableCredential" + ], + "grants": { + "urn:ietf:params:oauth:grant-type:pre-authorized_code": { + "pre-authorized_code": "4jLs9xZHEfqcoow0kHE7d1a8hUk6Sy-5bVSV2MqBUGUgiFFQi-ImL62T-FmLIo8hKA1UdMPH0lM1xAgcFkJfxIw9L-lI3mVs0hRT8YVwsEM1ma6N3wzuCdwtMU4bcwKp", + "user_pin_required": true + } + } + }, + "original_credential_offer": { + "credential_type": [ + "OpenBadgeCredentialUrl", + "VerifiableCredential" + ], + "issuer": "https://issuer.research.identiproof.io", + "pre-authorized_code": "4jLs9xZHEfqcoow0kHE7d1a8hUk6Sy-5bVSV2MqBUGUgiFFQi-ImL62T-FmLIo8hKA1UdMPH0lM1xAgcFkJfxIw9L-lI3mVs0hRT8YVwsEM1ma6N3wzuCdwtMU4bcwKp", + "user_pin_required": "true" + }, + "preAuthorizedCode": "4jLs9xZHEfqcoow0kHE7d1a8hUk6Sy-5bVSV2MqBUGUgiFFQi-ImL62T-FmLIo8hKA1UdMPH0lM1xAgcFkJfxIw9L-lI3mVs0hRT8YVwsEM1ma6N3wzuCdwtMU4bcwKp", + "scheme": "https", + "supportedFlows": [ + "Pre-Authorized Code Flow" + ], + "userPinRequired": true, + "version": 1008 + }, + "endpointMetadata": { + "authorizationServerMetadata": { + "authorization_endpoint": "https://auth.research.identiproof.io/oauth2/authorize", + "code_challenge_methods_supported": [ + "S256" + ], + "grant_types_supported": [ + "authorization_code", + "urn:ietf:params:oauth:grant-type:pre-authorized_code", + "client_credentials", + "refresh_token" + ], + "introspection_endpoint": "https://auth.research.identiproof.io/oauth2/introspect", + "introspection_endpoint_auth_methods_supported": [ + "client_secret_basic", + "client_secret_post", + "client_secret_jwt", + "private_key_jwt" + ], + "issuer": "https://auth.research.identiproof.io", + "jwks_uri": "https://auth.research.identiproof.io/oauth2/jwks", + "response_types_supported": [ + "code" + ], + "revocation_endpoint": "https://auth.research.identiproof.io/oauth2/revoke", + "revocation_endpoint_auth_methods_supported": [ + "client_secret_basic", + "client_secret_post", + "client_secret_jwt", + "private_key_jwt" + ], + "token_endpoint": "https://auth.research.identiproof.io/oauth2/token", + "token_endpoint_auth_methods_supported": [ + "client_secret_basic", + "client_secret_post", + "client_secret_jwt", + "private_key_jwt" + ] + }, + "authorizationServerType": "OID4VCI", + "authorization_endpoint": "https://auth.research.identiproof.io/oauth2/authorize", + "authorization_server": "https://auth.research.identiproof.io", + "credentialIssuerMetadata": { + "authorization_server": "https://auth.research.identiproof.io", + "credential_endpoint": "https://issuer.research.identiproof.io/credential", + "credentials_supported": { + "Cyber Security Certificate": { + "formats": { + "jwt_vc": { + "cryptographic_binding_methods_supported": [ + "did" + ], + "cryptographic_suites_supported": [ + "ES256" + ], + "types": [ + "VerifiableCredential", + "Cyber Security Certificate" + ] + } + } + }, + "OpenBadgeCredential": { + "formats": { + "jwt_vc": { + "cryptographic_binding_methods_supported": [ + "did" + ], + "cryptographic_suites_supported": [ + "ES256" + ], + "types": [ + "VerifiableCredential", + "OpenBadgeCredential" + ] + } + } + }, + "OpenBadgeExtendedCredential": { + "formats": { + "jwt_vc": { + "cryptographic_binding_methods_supported": [ + "did" + ], + "cryptographic_suites_supported": [ + "ES256" + ], + "types": [ + "VerifiableCredential", + "OpenBadgeExtendedCredential" + ] + } + } + } + }, + "issuer": "https://issuer.research.identiproof.io", + "jwks_uri": "https://issuer.research.identiproof.io/.well-known/did.json" + }, + "credential_endpoint": "https://issuer.research.identiproof.io/credential", + "issuer": "https://issuer.research.identiproof.io", + "token_endpoint": "https://auth.research.identiproof.io/oauth2/token" + }, + "pkce": { + "codeChallengeMethod": "S256", + "disabled": false + } + }, + "serverMetadata": { + "authorizationServerMetadata": { + "authorization_endpoint": "https://auth.research.identiproof.io/oauth2/authorize", + "code_challenge_methods_supported": [ + "S256" + ], + "grant_types_supported": [ + "authorization_code", + "urn:ietf:params:oauth:grant-type:pre-authorized_code", + "client_credentials", + "refresh_token" + ], + "introspection_endpoint": "https://auth.research.identiproof.io/oauth2/introspect", + "introspection_endpoint_auth_methods_supported": [ + "client_secret_basic", + "client_secret_post", + "client_secret_jwt", + "private_key_jwt" + ], + "issuer": "https://auth.research.identiproof.io", + "jwks_uri": "https://auth.research.identiproof.io/oauth2/jwks", + "response_types_supported": [ + "code" + ], + "revocation_endpoint": "https://auth.research.identiproof.io/oauth2/revoke", + "revocation_endpoint_auth_methods_supported": [ + "client_secret_basic", + "client_secret_post", + "client_secret_jwt", + "private_key_jwt" + ], + "token_endpoint": "https://auth.research.identiproof.io/oauth2/token", + "token_endpoint_auth_methods_supported": [ + "client_secret_basic", + "client_secret_post", + "client_secret_jwt", + "private_key_jwt" + ] + }, + "authorizationServerType": "OID4VCI", + "authorization_endpoint": "https://auth.research.identiproof.io/oauth2/authorize", + "authorization_server": "https://auth.research.identiproof.io", + "credentialIssuerMetadata": { + "authorization_server": "https://auth.research.identiproof.io", + "credential_endpoint": "https://issuer.research.identiproof.io/credential", + "credentials_supported": { + "Cyber Security Certificate": { + "formats": { + "jwt_vc": { + "cryptographic_binding_methods_supported": [ + "did" + ], + "cryptographic_suites_supported": [ + "ES256" + ], + "types": [ + "VerifiableCredential", + "Cyber Security Certificate" + ] + } + } + }, + "OpenBadgeCredential": { + "formats": { + "jwt_vc": { + "cryptographic_binding_methods_supported": [ + "did" + ], + "cryptographic_suites_supported": [ + "ES256" + ], + "types": [ + "VerifiableCredential", + "OpenBadgeCredential" + ] + } + } + }, + "OpenBadgeExtendedCredential": { + "formats": { + "jwt_vc": { + "cryptographic_binding_methods_supported": [ + "did" + ], + "cryptographic_suites_supported": [ + "ES256" + ], + "types": [ + "VerifiableCredential", + "OpenBadgeExtendedCredential" + ] + } + } + } + }, + "issuer": "https://issuer.research.identiproof.io", + "jwks_uri": "https://issuer.research.identiproof.io/.well-known/did.json" + }, + "credential_endpoint": "https://issuer.research.identiproof.io/credential", + "issuer": "https://issuer.research.identiproof.io", + "token_endpoint": "https://auth.research.identiproof.io/oauth2/token" + } +} + +export const GET_INITIATION_DATA_PRE_AUTHORIZED_OPENID_CREDENTIAL_OFFER = { + "credentialBranding": {}, + "credentialsSupported": [], + "openID4VCIClientState": { + "authorizationRequestOpts": { + "redirectUri": "openid-credential-offer://" + }, + "credentialIssuer": "https://issuer.research.identiproof.io", + "credentialOffer": { + "baseUrl": "openid-credential-offer://", + "credential_offer": { + "credential_issuer": "https://issuer.research.identiproof.io", + "credentials": [ + { + "format": "jwt_vc_json", + "types": [ + "VerifiableCredential", + "UniversityDegreeCredential" + ] + } + ], + "grants": { + "urn:ietf:params:oauth:grant-type:pre-authorized_code": { + "pre-authorized_code": "adhjhdjajkdkhjhdj", + "user_pin_required": true + } + } + }, + "original_credential_offer": { + "credential_issuer": "https://issuer.research.identiproof.io", + "credentials": [ + { + "format": "jwt_vc_json", + "types": [ + "VerifiableCredential", + "UniversityDegreeCredential" + ] + } + ], + "grants": { + "urn:ietf:params:oauth:grant-type:pre-authorized_code": { + "pre-authorized_code": "adhjhdjajkdkhjhdj", + "user_pin_required": true + } + } + }, + "preAuthorizedCode": "adhjhdjajkdkhjhdj", + "scheme": "openid-credential-offer", + "supportedFlows": [ + "Pre-Authorized Code Flow" + ], + "userPinRequired": true, + "version": 1011 + }, + "endpointMetadata": { + "authorizationServerMetadata": { + "authorization_endpoint": "https://auth.research.identiproof.io/oauth2/authorize", + "code_challenge_methods_supported": [ + "S256" + ], + "grant_types_supported": [ + "authorization_code", + "urn:ietf:params:oauth:grant-type:pre-authorized_code", + "client_credentials", + "refresh_token" + ], + "introspection_endpoint": "https://auth.research.identiproof.io/oauth2/introspect", + "introspection_endpoint_auth_methods_supported": [ + "client_secret_basic", + "client_secret_post", + "client_secret_jwt", + "private_key_jwt" + ], + "issuer": "https://auth.research.identiproof.io", + "jwks_uri": "https://auth.research.identiproof.io/oauth2/jwks", + "response_types_supported": [ + "code" + ], + "revocation_endpoint": "https://auth.research.identiproof.io/oauth2/revoke", + "revocation_endpoint_auth_methods_supported": [ + "client_secret_basic", + "client_secret_post", + "client_secret_jwt", + "private_key_jwt" + ], + "token_endpoint": "https://auth.research.identiproof.io/oauth2/token", + "token_endpoint_auth_methods_supported": [ + "client_secret_basic", + "client_secret_post", + "client_secret_jwt", + "private_key_jwt" + ] + }, + "authorizationServerType": "OID4VCI", + "authorization_endpoint": "https://auth.research.identiproof.io/oauth2/authorize", + "authorization_server": "https://auth.research.identiproof.io", + "credentialIssuerMetadata": { + "authorization_server": "https://auth.research.identiproof.io", + "credential_endpoint": "https://issuer.research.identiproof.io/credential", + "credentials_supported": { + "Cyber Security Certificate": { + "formats": { + "jwt_vc": { + "cryptographic_binding_methods_supported": [ + "did" + ], + "cryptographic_suites_supported": [ + "ES256" + ], + "types": [ + "VerifiableCredential", + "Cyber Security Certificate" + ] + } + } + }, + "OpenBadgeCredential": { + "formats": { + "jwt_vc": { + "cryptographic_binding_methods_supported": [ + "did" + ], + "cryptographic_suites_supported": [ + "ES256" + ], + "types": [ + "VerifiableCredential", + "OpenBadgeCredential" + ] + } + } + }, + "OpenBadgeExtendedCredential": { + "formats": { + "jwt_vc": { + "cryptographic_binding_methods_supported": [ + "did" + ], + "cryptographic_suites_supported": [ + "ES256" + ], + "types": [ + "VerifiableCredential", + "OpenBadgeExtendedCredential" + ] + } + } + } + }, + "issuer": "https://issuer.research.identiproof.io", + "jwks_uri": "https://issuer.research.identiproof.io/.well-known/did.json" + }, + "credential_endpoint": "https://issuer.research.identiproof.io/credential", + "issuer": "https://issuer.research.identiproof.io", + "token_endpoint": "https://auth.research.identiproof.io/oauth2/token" + }, + "pkce": { + "codeChallengeMethod": "S256", + "disabled": false + } + }, + "serverMetadata": { + "authorizationServerMetadata": { + "authorization_endpoint": "https://auth.research.identiproof.io/oauth2/authorize", + "code_challenge_methods_supported": [ + "S256" + ], + "grant_types_supported": [ + "authorization_code", + "urn:ietf:params:oauth:grant-type:pre-authorized_code", + "client_credentials", + "refresh_token" + ], + "introspection_endpoint": "https://auth.research.identiproof.io/oauth2/introspect", + "introspection_endpoint_auth_methods_supported": [ + "client_secret_basic", + "client_secret_post", + "client_secret_jwt", + "private_key_jwt" + ], + "issuer": "https://auth.research.identiproof.io", + "jwks_uri": "https://auth.research.identiproof.io/oauth2/jwks", + "response_types_supported": [ + "code" + ], + "revocation_endpoint": "https://auth.research.identiproof.io/oauth2/revoke", + "revocation_endpoint_auth_methods_supported": [ + "client_secret_basic", + "client_secret_post", + "client_secret_jwt", + "private_key_jwt" + ], + "token_endpoint": "https://auth.research.identiproof.io/oauth2/token", + "token_endpoint_auth_methods_supported": [ + "client_secret_basic", + "client_secret_post", + "client_secret_jwt", + "private_key_jwt" + ] + }, + "authorizationServerType": "OID4VCI", + "authorization_endpoint": "https://auth.research.identiproof.io/oauth2/authorize", + "authorization_server": "https://auth.research.identiproof.io", + "credentialIssuerMetadata": { + "authorization_server": "https://auth.research.identiproof.io", + "credential_endpoint": "https://issuer.research.identiproof.io/credential", + "credentials_supported": { + "Cyber Security Certificate": { + "formats": { + "jwt_vc": { + "cryptographic_binding_methods_supported": [ + "did" + ], + "cryptographic_suites_supported": [ + "ES256" + ], + "types": [ + "VerifiableCredential", + "Cyber Security Certificate" + ] + } + } + }, + "OpenBadgeCredential": { + "formats": { + "jwt_vc": { + "cryptographic_binding_methods_supported": [ + "did" + ], + "cryptographic_suites_supported": [ + "ES256" + ], + "types": [ + "VerifiableCredential", + "OpenBadgeCredential" + ] + } + } + }, + "OpenBadgeExtendedCredential": { + "formats": { + "jwt_vc": { + "cryptographic_binding_methods_supported": [ + "did" + ], + "cryptographic_suites_supported": [ + "ES256" + ], + "types": [ + "VerifiableCredential", + "OpenBadgeExtendedCredential" + ] + } + } + } + }, + "issuer": "https://issuer.research.identiproof.io", + "jwks_uri": "https://issuer.research.identiproof.io/.well-known/did.json" + }, + "credential_endpoint": "https://issuer.research.identiproof.io/credential", + "issuer": "https://issuer.research.identiproof.io", + "token_endpoint": "https://auth.research.identiproof.io/oauth2/token" + } +} + +export const GET_INITIATION_DATA_PRE_AUTHORIZED_OPENID_INITIATE_ISSUANCE = { + "credentialBranding": {}, + "credentialsSupported": [], + "openID4VCIClientState": { + "authorizationRequestOpts": { + "redirectUri": "openid-credential-offer://" + }, + "credentialIssuer": "https://issuer.research.identiproof.io", + "credentialOffer": { + "baseUrl": "openid-initiate-issuance://", + "credential_offer": { + "credential_issuer": "https://issuer.research.identiproof.io", + "credentials": [ + "OpenBadgeCredentialUrl", + "VerifiableCredential" + ], + "grants": { + "urn:ietf:params:oauth:grant-type:pre-authorized_code": { + "pre-authorized_code": "4jLs9xZHEfqcoow0kHE7d1a8hUk6Sy-5bVSV2MqBUGUgiFFQi-ImL62T-FmLIo8hKA1UdMPH0lM1xAgcFkJfxIw9L-lI3mVs0hRT8YVwsEM1ma6N3wzuCdwtMU4bcwKp", + "user_pin_required": true + } + } + }, + "original_credential_offer": { + "credential_type": [ + "OpenBadgeCredentialUrl", + "VerifiableCredential" + ], + "issuer": "https://issuer.research.identiproof.io", + "pre-authorized_code": "4jLs9xZHEfqcoow0kHE7d1a8hUk6Sy-5bVSV2MqBUGUgiFFQi-ImL62T-FmLIo8hKA1UdMPH0lM1xAgcFkJfxIw9L-lI3mVs0hRT8YVwsEM1ma6N3wzuCdwtMU4bcwKp", + "user_pin_required": "true" + }, + "preAuthorizedCode": "4jLs9xZHEfqcoow0kHE7d1a8hUk6Sy-5bVSV2MqBUGUgiFFQi-ImL62T-FmLIo8hKA1UdMPH0lM1xAgcFkJfxIw9L-lI3mVs0hRT8YVwsEM1ma6N3wzuCdwtMU4bcwKp", + "scheme": "openid-initiate-issuance", + "supportedFlows": [ + "Pre-Authorized Code Flow" + ], + "userPinRequired": true, + "version": 1008 + }, + "endpointMetadata": { + "authorizationServerMetadata": { + "authorization_endpoint": "https://auth.research.identiproof.io/oauth2/authorize", + "code_challenge_methods_supported": [ + "S256" + ], + "grant_types_supported": [ + "authorization_code", + "urn:ietf:params:oauth:grant-type:pre-authorized_code", + "client_credentials", + "refresh_token" + ], + "introspection_endpoint": "https://auth.research.identiproof.io/oauth2/introspect", + "introspection_endpoint_auth_methods_supported": [ + "client_secret_basic", + "client_secret_post", + "client_secret_jwt", + "private_key_jwt" + ], + "issuer": "https://auth.research.identiproof.io", + "jwks_uri": "https://auth.research.identiproof.io/oauth2/jwks", + "response_types_supported": [ + "code" + ], + "revocation_endpoint": "https://auth.research.identiproof.io/oauth2/revoke", + "revocation_endpoint_auth_methods_supported": [ + "client_secret_basic", + "client_secret_post", + "client_secret_jwt", + "private_key_jwt" + ], + "token_endpoint": "https://auth.research.identiproof.io/oauth2/token", + "token_endpoint_auth_methods_supported": [ + "client_secret_basic", + "client_secret_post", + "client_secret_jwt", + "private_key_jwt" + ] + }, + "authorizationServerType": "OID4VCI", + "authorization_endpoint": "https://auth.research.identiproof.io/oauth2/authorize", + "authorization_server": "https://auth.research.identiproof.io", + "credentialIssuerMetadata": { + "authorization_server": "https://auth.research.identiproof.io", + "credential_endpoint": "https://issuer.research.identiproof.io/credential", + "credentials_supported": { + "Cyber Security Certificate": { + "formats": { + "jwt_vc": { + "cryptographic_binding_methods_supported": [ + "did" + ], + "cryptographic_suites_supported": [ + "ES256" + ], + "types": [ + "VerifiableCredential", + "Cyber Security Certificate" + ] + } + } + }, + "OpenBadgeCredential": { + "formats": { + "jwt_vc": { + "cryptographic_binding_methods_supported": [ + "did" + ], + "cryptographic_suites_supported": [ + "ES256" + ], + "types": [ + "VerifiableCredential", + "OpenBadgeCredential" + ] + } + } + }, + "OpenBadgeExtendedCredential": { + "formats": { + "jwt_vc": { + "cryptographic_binding_methods_supported": [ + "did" + ], + "cryptographic_suites_supported": [ + "ES256" + ], + "types": [ + "VerifiableCredential", + "OpenBadgeExtendedCredential" + ] + } + } + } + }, + "issuer": "https://issuer.research.identiproof.io", + "jwks_uri": "https://issuer.research.identiproof.io/.well-known/did.json" + }, + "credential_endpoint": "https://issuer.research.identiproof.io/credential", + "issuer": "https://issuer.research.identiproof.io", + "token_endpoint": "https://auth.research.identiproof.io/oauth2/token" + }, + "pkce": { + "codeChallengeMethod": "S256", + "disabled": false + } + }, + "serverMetadata": { + "authorizationServerMetadata": { + "authorization_endpoint": "https://auth.research.identiproof.io/oauth2/authorize", + "code_challenge_methods_supported": [ + "S256" + ], + "grant_types_supported": [ + "authorization_code", + "urn:ietf:params:oauth:grant-type:pre-authorized_code", + "client_credentials", + "refresh_token" + ], + "introspection_endpoint": "https://auth.research.identiproof.io/oauth2/introspect", + "introspection_endpoint_auth_methods_supported": [ + "client_secret_basic", + "client_secret_post", + "client_secret_jwt", + "private_key_jwt" + ], + "issuer": "https://auth.research.identiproof.io", + "jwks_uri": "https://auth.research.identiproof.io/oauth2/jwks", + "response_types_supported": [ + "code" + ], + "revocation_endpoint": "https://auth.research.identiproof.io/oauth2/revoke", + "revocation_endpoint_auth_methods_supported": [ + "client_secret_basic", + "client_secret_post", + "client_secret_jwt", + "private_key_jwt" + ], + "token_endpoint": "https://auth.research.identiproof.io/oauth2/token", + "token_endpoint_auth_methods_supported": [ + "client_secret_basic", + "client_secret_post", + "client_secret_jwt", + "private_key_jwt" + ] + }, + "authorizationServerType": "OID4VCI", + "authorization_endpoint": "https://auth.research.identiproof.io/oauth2/authorize", + "authorization_server": "https://auth.research.identiproof.io", + "credentialIssuerMetadata": { + "authorization_server": "https://auth.research.identiproof.io", + "credential_endpoint": "https://issuer.research.identiproof.io/credential", + "credentials_supported": { + "Cyber Security Certificate": { + "formats": { + "jwt_vc": { + "cryptographic_binding_methods_supported": [ + "did" + ], + "cryptographic_suites_supported": [ + "ES256" + ], + "types": [ + "VerifiableCredential", + "Cyber Security Certificate" + ] + } + } + }, + "OpenBadgeCredential": { + "formats": { + "jwt_vc": { + "cryptographic_binding_methods_supported": [ + "did" + ], + "cryptographic_suites_supported": [ + "ES256" + ], + "types": [ + "VerifiableCredential", + "OpenBadgeCredential" + ] + } + } + }, + "OpenBadgeExtendedCredential": { + "formats": { + "jwt_vc": { + "cryptographic_binding_methods_supported": [ + "did" + ], + "cryptographic_suites_supported": [ + "ES256" + ], + "types": [ + "VerifiableCredential", + "OpenBadgeExtendedCredential" + ] + } + } + } + }, + "issuer": "https://issuer.research.identiproof.io", + "jwks_uri": "https://issuer.research.identiproof.io/.well-known/did.json" + }, + "credential_endpoint": "https://issuer.research.identiproof.io/credential", + "issuer": "https://issuer.research.identiproof.io", + "token_endpoint": "https://auth.research.identiproof.io/oauth2/token" + } +} + +export const GET_INITIATION_DATA_AUTHORIZATION_CODE_HTTPS = { + "authorizationCodeURL": expect.any(String), + "credentialBranding": {}, + "credentialsSupported": [], + "openID4VCIClientState": { + "authorizationRequestOpts": { + "redirectUri": "openid-credential-offer://" + }, + "authorizationURL": expect.any(String), + "credentialIssuer": "https://issuer.research.identiproof.io", + "credentialOffer": { + "baseUrl": "https://issuer.research.identiproof.io", + "credential_offer": { + "credential_issuer": "https://issuer.research.identiproof.io", + "credentials": [ + { + "format": "jwt_vc_json", + "types": [ + "VerifiableCredential", + "UniversityDegreeCredential" + ] + } + ], + "grants": { + "authorization_code": { + "issuer_state": "eyJhbGciOiJSU0Et...FYUaBy" + } + } + }, + "issuerState": "eyJhbGciOiJSU0Et...FYUaBy", + "original_credential_offer": { + "credential_issuer": "https://issuer.research.identiproof.io", + "credentials": [ + { + "format": "jwt_vc_json", + "types": [ + "VerifiableCredential", + "UniversityDegreeCredential" + ] + } + ], + "grants": { + "authorization_code": { + "issuer_state": "eyJhbGciOiJSU0Et...FYUaBy" + } + } + }, + "scheme": "https", + "supportedFlows": [ + "Authorization Code Flow" + ], + "userPinRequired": false, + "version": 1011 + }, + "endpointMetadata": { + "authorizationServerMetadata": { + "authorization_endpoint": "https://auth.research.identiproof.io/oauth2/authorize", + "code_challenge_methods_supported": [ + "S256" + ], + "grant_types_supported": [ + "authorization_code", + "urn:ietf:params:oauth:grant-type:pre-authorized_code", + "client_credentials", + "refresh_token" + ], + "introspection_endpoint": "https://auth.research.identiproof.io/oauth2/introspect", + "introspection_endpoint_auth_methods_supported": [ + "client_secret_basic", + "client_secret_post", + "client_secret_jwt", + "private_key_jwt" + ], + "issuer": "https://auth.research.identiproof.io", + "jwks_uri": "https://auth.research.identiproof.io/oauth2/jwks", + "response_types_supported": [ + "code" + ], + "revocation_endpoint": "https://auth.research.identiproof.io/oauth2/revoke", + "revocation_endpoint_auth_methods_supported": [ + "client_secret_basic", + "client_secret_post", + "client_secret_jwt", + "private_key_jwt" + ], + "token_endpoint": "https://auth.research.identiproof.io/oauth2/token", + "token_endpoint_auth_methods_supported": [ + "client_secret_basic", + "client_secret_post", + "client_secret_jwt", + "private_key_jwt" + ] + }, + "authorizationServerType": "OID4VCI", + "authorization_endpoint": "https://auth.research.identiproof.io/oauth2/authorize", + "authorization_server": "https://auth.research.identiproof.io", + "credentialIssuerMetadata": { + "authorization_server": "https://auth.research.identiproof.io", + "credential_endpoint": "https://issuer.research.identiproof.io/credential", + "credentials_supported": { + "Cyber Security Certificate": { + "formats": { + "jwt_vc": { + "cryptographic_binding_methods_supported": [ + "did" + ], + "cryptographic_suites_supported": [ + "ES256" + ], + "types": [ + "VerifiableCredential", + "Cyber Security Certificate" + ] + } + } + }, + "OpenBadgeCredential": { + "formats": { + "jwt_vc": { + "cryptographic_binding_methods_supported": [ + "did" + ], + "cryptographic_suites_supported": [ + "ES256" + ], + "types": [ + "VerifiableCredential", + "OpenBadgeCredential" + ] + } + } + }, + "OpenBadgeExtendedCredential": { + "formats": { + "jwt_vc": { + "cryptographic_binding_methods_supported": [ + "did" + ], + "cryptographic_suites_supported": [ + "ES256" + ], + "types": [ + "VerifiableCredential", + "OpenBadgeExtendedCredential" + ] + } + } + } + }, + "issuer": "https://issuer.research.identiproof.io", + "jwks_uri": "https://issuer.research.identiproof.io/.well-known/did.json" + }, + "credential_endpoint": "https://issuer.research.identiproof.io/credential", + "deferred_credential_endpoint": undefined, + "issuer": "https://issuer.research.identiproof.io", + "token_endpoint": "https://auth.research.identiproof.io/oauth2/token" + }, + "pkce": { + "codeChallenge": expect.any(String), + "codeChallengeMethod": "S256", + "codeVerifier": expect.any(String), + "disabled": false + } + }, + "serverMetadata": { + "authorizationServerMetadata": { + "authorization_endpoint": "https://auth.research.identiproof.io/oauth2/authorize", + "code_challenge_methods_supported": [ + "S256" + ], + "grant_types_supported": [ + "authorization_code", + "urn:ietf:params:oauth:grant-type:pre-authorized_code", + "client_credentials", + "refresh_token" + ], + "introspection_endpoint": "https://auth.research.identiproof.io/oauth2/introspect", + "introspection_endpoint_auth_methods_supported": [ + "client_secret_basic", + "client_secret_post", + "client_secret_jwt", + "private_key_jwt" + ], + "issuer": "https://auth.research.identiproof.io", + "jwks_uri": "https://auth.research.identiproof.io/oauth2/jwks", + "response_types_supported": [ + "code" + ], + "revocation_endpoint": "https://auth.research.identiproof.io/oauth2/revoke", + "revocation_endpoint_auth_methods_supported": [ + "client_secret_basic", + "client_secret_post", + "client_secret_jwt", + "private_key_jwt" + ], + "token_endpoint": "https://auth.research.identiproof.io/oauth2/token", + "token_endpoint_auth_methods_supported": [ + "client_secret_basic", + "client_secret_post", + "client_secret_jwt", + "private_key_jwt" + ] + }, + "authorizationServerType": "OID4VCI", + "authorization_endpoint": "https://auth.research.identiproof.io/oauth2/authorize", + "authorization_server": "https://auth.research.identiproof.io", + "credentialIssuerMetadata": { + "authorization_server": "https://auth.research.identiproof.io", + "credential_endpoint": "https://issuer.research.identiproof.io/credential", + "credentials_supported": { + "Cyber Security Certificate": { + "formats": { + "jwt_vc": { + "cryptographic_binding_methods_supported": [ + "did" + ], + "cryptographic_suites_supported": [ + "ES256" + ], + "types": [ + "VerifiableCredential", + "Cyber Security Certificate" + ] + } + } + }, + "OpenBadgeCredential": { + "formats": { + "jwt_vc": { + "cryptographic_binding_methods_supported": [ + "did" + ], + "cryptographic_suites_supported": [ + "ES256" + ], + "types": [ + "VerifiableCredential", + "OpenBadgeCredential" + ] + } + } + }, + "OpenBadgeExtendedCredential": { + "formats": { + "jwt_vc": { + "cryptographic_binding_methods_supported": [ + "did" + ], + "cryptographic_suites_supported": [ + "ES256" + ], + "types": [ + "VerifiableCredential", + "OpenBadgeExtendedCredential" + ] + } + } + } + }, + "issuer": "https://issuer.research.identiproof.io", + "jwks_uri": "https://issuer.research.identiproof.io/.well-known/did.json" + }, + "credential_endpoint": "https://issuer.research.identiproof.io/credential", + "issuer": "https://issuer.research.identiproof.io", + "token_endpoint": "https://auth.research.identiproof.io/oauth2/token" + } +} + +export const GET_INITIATION_DATA_PRE_AUTHORIZED_CODE_HTTPS = { + "credentialBranding": {}, + "credentialsSupported": [], + "openID4VCIClientState": { + "authorizationRequestOpts": { + "redirectUri": "openid-credential-offer://" + }, + "credentialIssuer": "https://issuer.research.identiproof.io", + "credentialOffer": { + "baseUrl": "https://issuer.research.identiproof.io", + "credential_offer": { + "credential_issuer": "https://issuer.research.identiproof.io", + "credentials": [ + { + "format": "jwt_vc_json", + "types": [ + "VerifiableCredential", + "UniversityDegreeCredential" + ] + } + ], + "grants": { + "urn:ietf:params:oauth:grant-type:pre-authorized_code": { + "pre-authorized_code": "adhjhdjajkdkhjhdj", + "user_pin_required": true + } + } + }, + "original_credential_offer": { + "credential_issuer": "https://issuer.research.identiproof.io", + "credentials": [ + { + "format": "jwt_vc_json", + "types": [ + "VerifiableCredential", + "UniversityDegreeCredential" + ] + } + ], + "grants": { + "urn:ietf:params:oauth:grant-type:pre-authorized_code": { + "pre-authorized_code": "adhjhdjajkdkhjhdj", + "user_pin_required": true + } + } + }, + "preAuthorizedCode": "adhjhdjajkdkhjhdj", + "scheme": "https", + "supportedFlows": [ + "Pre-Authorized Code Flow" + ], + "userPinRequired": true, + "version": 1011 + }, + "endpointMetadata": { + "authorizationServerMetadata": { + "authorization_endpoint": "https://auth.research.identiproof.io/oauth2/authorize", + "code_challenge_methods_supported": [ + "S256" + ], + "grant_types_supported": [ + "authorization_code", + "urn:ietf:params:oauth:grant-type:pre-authorized_code", + "client_credentials", + "refresh_token" + ], + "introspection_endpoint": "https://auth.research.identiproof.io/oauth2/introspect", + "introspection_endpoint_auth_methods_supported": [ + "client_secret_basic", + "client_secret_post", + "client_secret_jwt", + "private_key_jwt" + ], + "issuer": "https://auth.research.identiproof.io", + "jwks_uri": "https://auth.research.identiproof.io/oauth2/jwks", + "response_types_supported": [ + "code" + ], + "revocation_endpoint": "https://auth.research.identiproof.io/oauth2/revoke", + "revocation_endpoint_auth_methods_supported": [ + "client_secret_basic", + "client_secret_post", + "client_secret_jwt", + "private_key_jwt" + ], + "token_endpoint": "https://auth.research.identiproof.io/oauth2/token", + "token_endpoint_auth_methods_supported": [ + "client_secret_basic", + "client_secret_post", + "client_secret_jwt", + "private_key_jwt" + ] + }, + "authorizationServerType": "OID4VCI", + "authorization_endpoint": "https://auth.research.identiproof.io/oauth2/authorize", + "authorization_server": "https://auth.research.identiproof.io", + "credentialIssuerMetadata": { + "authorization_server": "https://auth.research.identiproof.io", + "credential_endpoint": "https://issuer.research.identiproof.io/credential", + "credentials_supported": { + "Cyber Security Certificate": { + "formats": { + "jwt_vc": { + "cryptographic_binding_methods_supported": [ + "did" + ], + "cryptographic_suites_supported": [ + "ES256" + ], + "types": [ + "VerifiableCredential", + "Cyber Security Certificate" + ] + } + } + }, + "OpenBadgeCredential": { + "formats": { + "jwt_vc": { + "cryptographic_binding_methods_supported": [ + "did" + ], + "cryptographic_suites_supported": [ + "ES256" + ], + "types": [ + "VerifiableCredential", + "OpenBadgeCredential" + ] + } + } + }, + "OpenBadgeExtendedCredential": { + "formats": { + "jwt_vc": { + "cryptographic_binding_methods_supported": [ + "did" + ], + "cryptographic_suites_supported": [ + "ES256" + ], + "types": [ + "VerifiableCredential", + "OpenBadgeExtendedCredential" + ] + } + } + } + }, + "issuer": "https://issuer.research.identiproof.io", + "jwks_uri": "https://issuer.research.identiproof.io/.well-known/did.json" + }, + "credential_endpoint": "https://issuer.research.identiproof.io/credential", + "issuer": "https://issuer.research.identiproof.io", + "token_endpoint": "https://auth.research.identiproof.io/oauth2/token" + }, + "pkce": { + "codeChallengeMethod": "S256", + "disabled": false + } + }, + "serverMetadata": { + "authorizationServerMetadata": { + "authorization_endpoint": "https://auth.research.identiproof.io/oauth2/authorize", + "code_challenge_methods_supported": [ + "S256" + ], + "grant_types_supported": [ + "authorization_code", + "urn:ietf:params:oauth:grant-type:pre-authorized_code", + "client_credentials", + "refresh_token" + ], + "introspection_endpoint": "https://auth.research.identiproof.io/oauth2/introspect", + "introspection_endpoint_auth_methods_supported": [ + "client_secret_basic", + "client_secret_post", + "client_secret_jwt", + "private_key_jwt" + ], + "issuer": "https://auth.research.identiproof.io", + "jwks_uri": "https://auth.research.identiproof.io/oauth2/jwks", + "response_types_supported": [ + "code" + ], + "revocation_endpoint": "https://auth.research.identiproof.io/oauth2/revoke", + "revocation_endpoint_auth_methods_supported": [ + "client_secret_basic", + "client_secret_post", + "client_secret_jwt", + "private_key_jwt" + ], + "token_endpoint": "https://auth.research.identiproof.io/oauth2/token", + "token_endpoint_auth_methods_supported": [ + "client_secret_basic", + "client_secret_post", + "client_secret_jwt", + "private_key_jwt" + ] + }, + "authorizationServerType": "OID4VCI", + "authorization_endpoint": "https://auth.research.identiproof.io/oauth2/authorize", + "authorization_server": "https://auth.research.identiproof.io", + "credentialIssuerMetadata": { + "authorization_server": "https://auth.research.identiproof.io", + "credential_endpoint": "https://issuer.research.identiproof.io/credential", + "credentials_supported": { + "Cyber Security Certificate": { + "formats": { + "jwt_vc": { + "cryptographic_binding_methods_supported": [ + "did" + ], + "cryptographic_suites_supported": [ + "ES256" + ], + "types": [ + "VerifiableCredential", + "Cyber Security Certificate" + ] + } + } + }, + "OpenBadgeCredential": { + "formats": { + "jwt_vc": { + "cryptographic_binding_methods_supported": [ + "did" + ], + "cryptographic_suites_supported": [ + "ES256" + ], + "types": [ + "VerifiableCredential", + "OpenBadgeCredential" + ] + } + } + }, + "OpenBadgeExtendedCredential": { + "formats": { + "jwt_vc": { + "cryptographic_binding_methods_supported": [ + "did" + ], + "cryptographic_suites_supported": [ + "ES256" + ], + "types": [ + "VerifiableCredential", + "OpenBadgeExtendedCredential" + ] + } + } + } + }, + "issuer": "https://issuer.research.identiproof.io", + "jwks_uri": "https://issuer.research.identiproof.io/.well-known/did.json" + }, + "credential_endpoint": "https://issuer.research.identiproof.io/credential", + "issuer": "https://issuer.research.identiproof.io", + "token_endpoint": "https://auth.research.identiproof.io/oauth2/token" + } +} + +export const IDENTIPROOF_ISSUER_URL = 'https://issuer.research.identiproof.io'; +export const IDENTIPROOF_AS_URL = 'https://auth.research.identiproof.io'; + +export const IDENTIPROOF_AS_METADATA = { + issuer: 'https://auth.research.identiproof.io', + authorization_endpoint: 'https://auth.research.identiproof.io/oauth2/authorize', + token_endpoint: 'https://auth.research.identiproof.io/oauth2/token', + token_endpoint_auth_methods_supported: ['client_secret_basic', 'client_secret_post', 'client_secret_jwt', 'private_key_jwt'], + jwks_uri: 'https://auth.research.identiproof.io/oauth2/jwks', + response_types_supported: ['code'], + grant_types_supported: ['authorization_code', 'urn:ietf:params:oauth:grant-type:pre-authorized_code', 'client_credentials', 'refresh_token'], + revocation_endpoint: 'https://auth.research.identiproof.io/oauth2/revoke', + revocation_endpoint_auth_methods_supported: ['client_secret_basic', 'client_secret_post', 'client_secret_jwt', 'private_key_jwt'], + introspection_endpoint: 'https://auth.research.identiproof.io/oauth2/introspect', + introspection_endpoint_auth_methods_supported: ['client_secret_basic', 'client_secret_post', 'client_secret_jwt', 'private_key_jwt'], + code_challenge_methods_supported: ['S256'], +}; + +export const IDENTIPROOF_OID4VCI_METADATA = { + issuer: 'https://issuer.research.identiproof.io', + authorization_server: 'https://auth.research.identiproof.io', + credential_endpoint: 'https://issuer.research.identiproof.io/credential', + jwks_uri: 'https://issuer.research.identiproof.io/.well-known/did.json', + credentials_supported: { + 'Cyber Security Certificate': { + formats: { + jwt_vc: { + types: ['VerifiableCredential', 'Cyber Security Certificate'], + cryptographic_binding_methods_supported: ['did'], + cryptographic_suites_supported: ['ES256'], + }, + }, + }, + OpenBadgeCredential: { + formats: { + jwt_vc: { + types: ['VerifiableCredential', 'OpenBadgeCredential'], + cryptographic_binding_methods_supported: ['did'], + cryptographic_suites_supported: ['ES256'], + }, + }, + }, + OpenBadgeExtendedCredential: { + formats: { + jwt_vc: { + types: ['VerifiableCredential', 'OpenBadgeExtendedCredential'], + cryptographic_binding_methods_supported: ['did'], + cryptographic_suites_supported: ['ES256'], + }, + }, + }, + }, +}; diff --git a/packages/oid4vci-holder/__tests__/shared/eventLoggerAgentLogic.ts b/packages/oid4vci-holder/__tests__/shared/eventLoggerAgentLogic.ts deleted file mode 100644 index c63e5f9c7..000000000 --- a/packages/oid4vci-holder/__tests__/shared/eventLoggerAgentLogic.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { TAgent } from '@veramo/core' -import { IOID4VCIHolder } from '../../src' - -type ConfiguredAgent = TAgent - -export default (testContext: { getAgent: () => ConfiguredAgent; setup: () => Promise; tearDown: () => Promise }): void => { - describe.skip('Event Logger Agent Plugin', (): void => { - let agent: ConfiguredAgent - - beforeAll(async (): Promise => { - await testContext.setup() - agent = testContext.getAgent() - }) - - afterAll(testContext.tearDown) - - it('should store audit event', async (): Promise => { - expect(agent).toBeDefined() - }) - }) -} diff --git a/packages/oid4vci-holder/__tests__/shared/oid4vciHolderLogicAgentLogic.ts b/packages/oid4vci-holder/__tests__/shared/oid4vciHolderLogicAgentLogic.ts new file mode 100644 index 000000000..e63ea5ae1 --- /dev/null +++ b/packages/oid4vci-holder/__tests__/shared/oid4vciHolderLogicAgentLogic.ts @@ -0,0 +1,105 @@ +import { TAgent } from '@veramo/core' +import { IOID4VCIHolder } from '../../src' +import {AccessTokenResponse, WellKnownEndpoints} from "@sphereon/oid4vci-common"; +import nock = require("nock"); +import { + GET_INITIATION_DATA_AUTHORIZATION_CODE_HTTPS, + GET_INITIATION_DATA_PRE_AUTHORIZED_CODE_HTTPS, + GET_INITIATION_DATA_PRE_AUTHORIZED_OPENID_INITIATE_ISSUANCE, + GET_INITIATION_DATA_PRE_AUTHORIZED_OPENID_CREDENTIAL_OFFER, + IDENTIPROOF_AS_METADATA, + IDENTIPROOF_AS_URL, + IDENTIPROOF_ISSUER_URL, + IDENTIPROOF_OID4VCI_METADATA, GET_INITIATION_DATA_PRE_AUTHORIZED_HTTPS_INITIATE_FLOW +} from "./MetadataMocks"; + +type ConfiguredAgent = TAgent + +const mockedAccessTokenResponse: AccessTokenResponse = { + access_token: 'ey6546.546654.64565', + authorization_pending: false, + c_nonce: 'c_nonce2022101300', + c_nonce_expires_in: 2025101300, + interval: 2025101300, + token_type: 'Bearer', +}; +const mockedVC = + 'eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCJ9.eyJ2YyI6eyJAY29udGV4dCI6WyJodHRwczovL3d3dy53My5vcmcvMjAxOC9jcmVkZW50aWFscy92MSIsImh0dHBzOi8vd3d3LnczLm9yZy8yMDE4L2NyZWRlbnRpYWxzL2V4YW1wbGVzL3YxIl0sImlkIjoiaHR0cDovL2V4YW1wbGUuZWR1L2NyZWRlbnRpYWxzLzM3MzIiLCJ0eXBlIjpbIlZlcmlmaWFibGVDcmVkZW50aWFsIiwiVW5pdmVyc2l0eURlZ3JlZUNyZWRlbnRpYWwiXSwiaXNzdWVyIjoiaHR0cHM6Ly9leGFtcGxlLmVkdS9pc3N1ZXJzLzU2NTA0OSIsImlzc3VhbmNlRGF0ZSI6IjIwMTAtMDEtMDFUMDA6MDA6MDBaIiwiY3JlZGVudGlhbFN1YmplY3QiOnsiaWQiOiJkaWQ6ZXhhbXBsZTplYmZlYjFmNzEyZWJjNmYxYzI3NmUxMmVjMjEiLCJkZWdyZWUiOnsidHlwZSI6IkJhY2hlbG9yRGVncmVlIiwibmFtZSI6IkJhY2hlbG9yIG9mIFNjaWVuY2UgYW5kIEFydHMifX19LCJpc3MiOiJodHRwczovL2V4YW1wbGUuZWR1L2lzc3VlcnMvNTY1MDQ5IiwibmJmIjoxMjYyMzA0MDAwLCJqdGkiOiJodHRwOi8vZXhhbXBsZS5lZHUvY3JlZGVudGlhbHMvMzczMiIsInN1YiI6ImRpZDpleGFtcGxlOmViZmViMWY3MTJlYmM2ZjFjMjc2ZTEyZWMyMSJ9.z5vgMTK1nfizNCg5N-niCOL3WUIAL7nXy-nGhDZYO_-PNGeE-0djCpWAMH8fD8eWSID5PfkPBYkx_dfLJnQ7NA'; +const INITIATE_QR_PRE_AUTHORIZED = 'openid-initiate-issuance://?issuer=https%3A%2F%2Fissuer.research.identiproof.io&credential_type=OpenBadgeCredentialUrl&pre-authorized_code=4jLs9xZHEfqcoow0kHE7d1a8hUk6Sy-5bVSV2MqBUGUgiFFQi-ImL62T-FmLIo8hKA1UdMPH0lM1xAgcFkJfxIw9L-lI3mVs0hRT8YVwsEM1ma6N3wzuCdwtMU4bcwKp&user_pin_required=true'; +const OFFER_QR_PRE_AUTHORIZED = 'openid-credential-offer://?credential_offer%3D%7B%22credential_issuer%22%3A%22https%3A%2F%2Fissuer.research.identiproof.io%22%2C%22credentials%22%3A%5B%7B%22format%22%3A%22jwt_vc_json%22%2C%22types%22%3A%5B%22VerifiableCredential%22%2C%22UniversityDegreeCredential%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%22adhjhdjajkdkhjhdj%22%2C%22user_pin_required%22%3Atrue%7D%7D%7D'; +const HTTPS_INITIATE_QR = 'https://issuer.research.identiproof.io?issuer=https%3A%2F%2Fissuer.research.identiproof.io&credential_type=OpenBadgeCredentialUrl&pre-authorized_code=4jLs9xZHEfqcoow0kHE7d1a8hUk6Sy-5bVSV2MqBUGUgiFFQi-ImL62T-FmLIo8hKA1UdMPH0lM1xAgcFkJfxIw9L-lI3mVs0hRT8YVwsEM1ma6N3wzuCdwtMU4bcwKp&user_pin_required=true' +const HTTPS_OFFER_QR_AUTHORIZATION_CODE = 'https://issuer.research.identiproof.io?credential_offer%3D%7B%22credential_issuer%22%3A%22https%3A%2F%2Fissuer.research.identiproof.io%22%2C%22credentials%22%3A%5B%7B%22format%22%3A%22jwt_vc_json%22%2C%22types%22%3A%5B%22VerifiableCredential%22%2C%22UniversityDegreeCredential%22%5D%7D%5D%2C%22grants%22%3A%7B%22authorization_code%22%3A%7B%22issuer_state%22%3A%22eyJhbGciOiJSU0Et...FYUaBy%22%7D%7D%7D'; +const HTTPS_OFFER_QR_PRE_AUTHORIZED = 'https://issuer.research.identiproof.io?credential_offer%3D%7B%22credential_issuer%22%3A%22https%3A%2F%2Fissuer.research.identiproof.io%22%2C%22credentials%22%3A%5B%7B%22format%22%3A%22jwt_vc_json%22%2C%22types%22%3A%5B%22VerifiableCredential%22%2C%22UniversityDegreeCredential%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%22adhjhdjajkdkhjhdj%22%2C%22user_pin_required%22%3Atrue%7D%7D%7D' + +function succeedWithAFullFlowWithClientSetup() { + nock(IDENTIPROOF_ISSUER_URL).get('/.well-known/openid-credential-issuer').reply(200, JSON.stringify(IDENTIPROOF_OID4VCI_METADATA)); + nock(IDENTIPROOF_AS_URL).get('/.well-known/oauth-authorization-server').reply(200, JSON.stringify(IDENTIPROOF_AS_METADATA)); + nock(IDENTIPROOF_AS_URL).get(WellKnownEndpoints.OPENID_CONFIGURATION).reply(404, {}); + nock(IDENTIPROOF_AS_URL) + .post(/oauth2\/token.*/) + .reply(200, JSON.stringify(mockedAccessTokenResponse)); + nock(IDENTIPROOF_ISSUER_URL) + .post(/credential/) + .reply(200, { + format: 'jwt-vc', + credential: mockedVC, + }); +} + +export default (testContext: { getAgent: () => ConfiguredAgent; setup: () => Promise; tearDown: () => Promise }): void => { + describe('OID4VI Holder Agent Plugin', (): void => { + let agent: ConfiguredAgent + + beforeAll(async (): Promise => { + await testContext.setup() + agent = testContext.getAgent() + }) + + afterAll(testContext.tearDown) + + it('should get initialization data using pre-authorized_code and openid-initiate-issuance draft < 9', async (): Promise => { + succeedWithAFullFlowWithClientSetup() + await expect(agent.oid4vciHolderGetInitiationData({ + requestData: { + uri: INITIATE_QR_PRE_AUTHORIZED + } + })).resolves.toEqual(GET_INITIATION_DATA_PRE_AUTHORIZED_OPENID_INITIATE_ISSUANCE) + }) + + it('should get initialization data using pre-authorized_code and draft 11 >', async (): Promise => { + succeedWithAFullFlowWithClientSetup() + await expect(agent.oid4vciHolderGetInitiationData({ + requestData: { + uri: OFFER_QR_PRE_AUTHORIZED + } + })).resolves.toEqual(GET_INITIATION_DATA_PRE_AUTHORIZED_OPENID_CREDENTIAL_OFFER) + }) + + it('should get initialization data using pre-authorized_code and https draft < 9', async (): Promise => { + succeedWithAFullFlowWithClientSetup() + await expect(agent.oid4vciHolderGetInitiationData({ + requestData: { + uri: HTTPS_INITIATE_QR + } + })).resolves.toEqual(GET_INITIATION_DATA_PRE_AUTHORIZED_HTTPS_INITIATE_FLOW) + }) + + it('should get initialization data using authorization_code and https draft 11 >', async (): Promise => { + succeedWithAFullFlowWithClientSetup() + await expect(agent.oid4vciHolderGetInitiationData({ + requestData: { + uri: HTTPS_OFFER_QR_AUTHORIZATION_CODE + } + })).resolves.toEqual(GET_INITIATION_DATA_AUTHORIZATION_CODE_HTTPS) + }) + + it('should get initialization data using pre-authorized_code and https draft 11 >', async (): Promise => { + succeedWithAFullFlowWithClientSetup() + await expect(agent.oid4vciHolderGetInitiationData({ + requestData: { + uri: HTTPS_OFFER_QR_PRE_AUTHORIZED + } + })).resolves.toEqual(GET_INITIATION_DATA_PRE_AUTHORIZED_CODE_HTTPS) + }) + }) +} diff --git a/packages/oid4vci-holder/package.json b/packages/oid4vci-holder/package.json index a1d08e054..8eebff25a 100644 --- a/packages/oid4vci-holder/package.json +++ b/packages/oid4vci-holder/package.json @@ -16,13 +16,13 @@ "dependencies": { "@sphereon/oid4vci-client": " 0.10.4-unstable.6", "@sphereon/oid4vci-common": " 0.10.4-unstable.6", - "@sphereon/ssi-sdk-ext.did-utils": "0.18.0", "@sphereon/ssi-sdk-ext.did-resolver-jwk": "0.18.0", + "@sphereon/ssi-sdk-ext.did-utils": "0.18.0", "@sphereon/ssi-sdk.contact-manager": "workspace:*", "@sphereon/ssi-sdk.core": "workspace:*", "@sphereon/ssi-sdk.data-store": "workspace:*", - "@sphereon/ssi-sdk.xstate-machine-persistence": "workspace:*", "@sphereon/ssi-sdk.issuance-branding": "workspace:*", + "@sphereon/ssi-sdk.xstate-machine-persistence": "workspace:*", "@sphereon/ssi-types": "workspace:*", "@veramo/core": "4.2.0", "@veramo/data-store": "4.2.0", @@ -38,6 +38,7 @@ "@types/uuid": "^9.0.8", "@veramo/remote-client": "4.2.0", "@veramo/remote-server": "4.2.0", + "nock": "^13.5.4", "typeorm": "^0.3.20", "typescript": "^5.4.2" }, diff --git a/packages/oid4vci-holder/src/agent/OID4VCIHolder.ts b/packages/oid4vci-holder/src/agent/OID4VCIHolder.ts index fa1d620f1..2c2a2d96c 100644 --- a/packages/oid4vci-holder/src/agent/OID4VCIHolder.ts +++ b/packages/oid4vci-holder/src/agent/OID4VCIHolder.ts @@ -197,7 +197,7 @@ export class OID4VCIHolder implements IAgentPlugin { if ( !requestData?.uri || - !(requestData?.uri.startsWith(RequestType.OPENID_INITIATE_ISSUANCE) || requestData?.uri.startsWith(RequestType.OPENID_CREDENTIAL_OFFER)) + !(requestData?.uri.startsWith(RequestType.OPENID_INITIATE_ISSUANCE) || requestData?.uri.startsWith(RequestType.OPENID_CREDENTIAL_OFFER) || requestData?.uri.startsWith(RequestType.HTTPS)) ) { return Promise.reject(Error(`Invalid OID4VCI credential offer URI: ${requestData?.uri}`)) } diff --git a/packages/oid4vci-holder/src/types/IOID4VCIHolder.ts b/packages/oid4vci-holder/src/types/IOID4VCIHolder.ts index d1968faf3..4668b4721 100644 --- a/packages/oid4vci-holder/src/types/IOID4VCIHolder.ts +++ b/packages/oid4vci-holder/src/types/IOID4VCIHolder.ts @@ -288,6 +288,7 @@ export type ErrorDetails = { export enum RequestType { OPENID_INITIATE_ISSUANCE = 'openid-initiate-issuance', OPENID_CREDENTIAL_OFFER = 'openid-credential-offer', + HTTPS = 'https' } export type CredentialTypeSelection = { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 9868cf02d..296ef7218 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -734,6 +734,9 @@ importers: '@veramo/remote-server': specifier: 4.2.0 version: 4.2.0(express@4.19.2) + nock: + specifier: ^13.5.4 + version: 13.5.4 typeorm: specifier: ^0.3.20 version: 0.3.20(pg@8.11.5)(sqlite3@5.1.7)(ts-node@10.9.2)