diff --git a/waltid-services/waltid-e2e-tests/src/test/kotlin/IssuerApi.kt b/waltid-services/waltid-e2e-tests/src/test/kotlin/IssuerApi.kt index 533d714d7..48c298531 100644 --- a/waltid-services/waltid-e2e-tests/src/test/kotlin/IssuerApi.kt +++ b/waltid-services/waltid-e2e-tests/src/test/kotlin/IssuerApi.kt @@ -4,7 +4,7 @@ import io.ktor.client.* import io.ktor.client.call.* import io.ktor.client.request.* -class IssuerApi(private val client: HttpClient) { +class IssuerApi(private val client: HttpClient, private val cbUrl: String? = null) { suspend fun jwt(request: IssuanceRequest, output: ((String) -> Unit)? = null) = issue( name = "/openid4vc/jwt/issue - issue jwt credential", url = "/openid4vc/jwt/issue", @@ -47,6 +47,9 @@ class IssuerApi(private val client: HttpClient) { private suspend fun issue(name: String, url: String, request: IssuanceRequest, output: ((String) -> Unit)? = null) = test(name) { client.post(url) { + if(!cbUrl.isNullOrEmpty()) { + header("statusCallbackUri", cbUrl) + } setBody(request) }.expectSuccess().apply { output?.invoke(body()) diff --git a/waltid-services/waltid-e2e-tests/src/test/kotlin/WaltidServicesE2ETests.kt b/waltid-services/waltid-e2e-tests/src/test/kotlin/WaltidServicesE2ETests.kt index b3d4a839c..bfccbd452 100644 --- a/waltid-services/waltid-e2e-tests/src/test/kotlin/WaltidServicesE2ETests.kt +++ b/waltid-services/waltid-e2e-tests/src/test/kotlin/WaltidServicesE2ETests.kt @@ -225,7 +225,10 @@ class WaltidServicesE2ETests { //region -Issuer / offer url- lateinit var offerUrl: String - val issuerApi = IssuerApi(client) + val issuerApi = IssuerApi(client, + // uncomment the following line, to test status callbacks, update webhook id as required. + // "https://webhook.site/d879094b-2275-4ae7-b1c5-ebfb9f08dfdb" + ) val issuanceRequest = Json.decodeFromJsonElement(jwtCredential) println("issuance-request:") println(issuanceRequest) diff --git a/waltid-services/waltid-issuer-api/src/main/kotlin/id/walt/issuer/issuance/CIProvider.kt b/waltid-services/waltid-issuer-api/src/main/kotlin/id/walt/issuer/issuance/CIProvider.kt index 9892ffa58..48d32d83a 100644 --- a/waltid-services/waltid-issuer-api/src/main/kotlin/id/walt/issuer/issuance/CIProvider.kt +++ b/waltid-services/waltid-issuer-api/src/main/kotlin/id/walt/issuer/issuance/CIProvider.kt @@ -68,14 +68,13 @@ open class CIProvider( val baseUrl: String = let { ConfigManager.getConfig().baseUrl }, val config: CredentialIssuerConfig = CredentialIssuerConfig(credentialConfigurationsSupported = ConfigManager.getConfig().parse()) ) { - private val log = KotlinLogging.logger { } val metadata get() = OpenID4VCI.createDefaultProviderMetadata(baseUrl).copy( credentialConfigurationsSupported = config.credentialConfigurationsSupported ) companion object { - + private val log = KotlinLogging.logger { } private val http = HttpClient() { install(ContentNegotiation) { json() @@ -93,13 +92,14 @@ open class CIProvider( suspend fun sendCallback(sessionId: String, type: String, data: JsonObject, callbackUrl: String) { try { - http.post(callbackUrl.replace("\$id", sessionId)) { + val response = http.post(callbackUrl.replace("\$id", sessionId)) { setBody(buildJsonObject { put("id", sessionId) put("type", type) put("data", data) }) } + log.trace { "Sent issuance status callback: $callbackUrl, $type, $sessionId; respone: ${response.status}" } } catch (ex: Exception) { throw IllegalArgumentException("Error sending HTTP POST request to issuer callback url.", ex) } @@ -235,7 +235,10 @@ open class CIProvider( issuerKey = resolvedIssuerKey, selectiveDisclosure = request.selectiveDisclosure, dataMapping = request.mapping, - x5Chain = request.x5Chain) + x5Chain = request.x5Chain).also { + if(!issuanceSession.callbackUrl.isNullOrEmpty()) + sendCallback(issuanceSession.id, "sdjwt_issue", buildJsonObject { put("sdjwt", it) }, issuanceSession.callbackUrl) + } else -> OpenID4VCI.generateW3CJwtVC( credentialRequest = credentialRequest, credentialData = vc, @@ -245,7 +248,10 @@ open class CIProvider( selectiveDisclosure = request.selectiveDisclosure, dataMapping = request.mapping, x5Chain = request.x5Chain - ) + ).also { + if(!issuanceSession.callbackUrl.isNullOrEmpty()) + sendCallback(issuanceSession.id, "jwt_issue", buildJsonObject { put("jwt", it) }, issuanceSession.callbackUrl) + } } }.also { log.debug { "Respond VC: $it" } } })) @@ -577,6 +583,11 @@ open class CIProvider( cNonce = generateProofOfPossessionNonceFor(session).cNonce, cNonceExpiresIn = session.expirationTimestamp - Clock.System.now(), state = session.authorizationRequest?.state - ) + ).also { + if(!session.callbackUrl.isNullOrEmpty()) + sendCallback(sessionId, "requested_token", buildJsonObject { + put("request", Json.encodeToJsonElement(session.issuanceRequests.first())) + }, session.callbackUrl) + } } }