diff --git a/lithic-kotlin-core/src/main/kotlin/com/lithic/api/client/LithicClient.kt b/lithic-kotlin-core/src/main/kotlin/com/lithic/api/client/LithicClient.kt index db085ea9..bbb3058f 100644 --- a/lithic-kotlin-core/src/main/kotlin/com/lithic/api/client/LithicClient.kt +++ b/lithic-kotlin-core/src/main/kotlin/com/lithic/api/client/LithicClient.kt @@ -42,8 +42,6 @@ interface LithicClient { fun responderEndpoints(): ResponderEndpointService - fun webhooks(): WebhookService - fun externalBankAccounts(): ExternalBankAccountService fun payments(): PaymentService diff --git a/lithic-kotlin-core/src/main/kotlin/com/lithic/api/client/LithicClientAsync.kt b/lithic-kotlin-core/src/main/kotlin/com/lithic/api/client/LithicClientAsync.kt index 80f0d10f..f5f1e765 100644 --- a/lithic-kotlin-core/src/main/kotlin/com/lithic/api/client/LithicClientAsync.kt +++ b/lithic-kotlin-core/src/main/kotlin/com/lithic/api/client/LithicClientAsync.kt @@ -42,8 +42,6 @@ interface LithicClientAsync { fun responderEndpoints(): ResponderEndpointServiceAsync - fun webhooks(): WebhookServiceAsync - fun externalBankAccounts(): ExternalBankAccountServiceAsync fun payments(): PaymentServiceAsync diff --git a/lithic-kotlin-core/src/main/kotlin/com/lithic/api/client/LithicClientAsyncImpl.kt b/lithic-kotlin-core/src/main/kotlin/com/lithic/api/client/LithicClientAsyncImpl.kt index 601b681b..6c231c04 100644 --- a/lithic-kotlin-core/src/main/kotlin/com/lithic/api/client/LithicClientAsyncImpl.kt +++ b/lithic-kotlin-core/src/main/kotlin/com/lithic/api/client/LithicClientAsyncImpl.kt @@ -69,8 +69,6 @@ constructor( ResponderEndpointServiceAsyncImpl(clientOptions) } - private val webhooks: WebhookServiceAsync by lazy { WebhookServiceAsyncImpl(clientOptions) } - private val externalBankAccounts: ExternalBankAccountServiceAsync by lazy { ExternalBankAccountServiceAsyncImpl(clientOptions) } @@ -126,8 +124,6 @@ constructor( override fun responderEndpoints(): ResponderEndpointServiceAsync = responderEndpoints - override fun webhooks(): WebhookServiceAsync = webhooks - override fun externalBankAccounts(): ExternalBankAccountServiceAsync = externalBankAccounts override fun payments(): PaymentServiceAsync = payments diff --git a/lithic-kotlin-core/src/main/kotlin/com/lithic/api/client/LithicClientImpl.kt b/lithic-kotlin-core/src/main/kotlin/com/lithic/api/client/LithicClientImpl.kt index 3111778d..b5a9054a 100644 --- a/lithic-kotlin-core/src/main/kotlin/com/lithic/api/client/LithicClientImpl.kt +++ b/lithic-kotlin-core/src/main/kotlin/com/lithic/api/client/LithicClientImpl.kt @@ -67,8 +67,6 @@ constructor( ResponderEndpointServiceImpl(clientOptions) } - private val webhooks: WebhookService by lazy { WebhookServiceImpl(clientOptions) } - private val externalBankAccounts: ExternalBankAccountService by lazy { ExternalBankAccountServiceImpl(clientOptions) } @@ -119,8 +117,6 @@ constructor( override fun responderEndpoints(): ResponderEndpointService = responderEndpoints - override fun webhooks(): WebhookService = webhooks - override fun externalBankAccounts(): ExternalBankAccountService = externalBankAccounts override fun payments(): PaymentService = payments diff --git a/lithic-kotlin-core/src/main/kotlin/com/lithic/api/models/CardGetEmbedHtmlParams.kt b/lithic-kotlin-core/src/main/kotlin/com/lithic/api/models/CardGetEmbedHtmlParams.kt deleted file mode 100644 index a40cc168..00000000 --- a/lithic-kotlin-core/src/main/kotlin/com/lithic/api/models/CardGetEmbedHtmlParams.kt +++ /dev/null @@ -1,366 +0,0 @@ -// File generated from our OpenAPI spec by Stainless. - -package com.lithic.api.models - -import com.fasterxml.jackson.annotation.JsonAnyGetter -import com.fasterxml.jackson.annotation.JsonAnySetter -import com.fasterxml.jackson.annotation.JsonProperty -import com.fasterxml.jackson.databind.annotation.JsonDeserialize -import com.lithic.api.core.ExcludeMissing -import com.lithic.api.core.JsonValue -import com.lithic.api.core.NoAutoDetect -import com.lithic.api.core.toUnmodifiable -import com.lithic.api.models.* -import java.time.OffsetDateTime -import java.util.Objects - -class CardGetEmbedHtmlParams -constructor( - private val token: String, - private val css: String?, - private val expiration: OffsetDateTime?, - private val targetOrigin: String?, - private val additionalQueryParams: Map>, - private val additionalHeaders: Map>, - private val additionalBodyProperties: Map, -) { - - fun token(): String = token - - fun css(): String? = css - - fun expiration(): OffsetDateTime? = expiration - - fun targetOrigin(): String? = targetOrigin - - internal fun getBody(): CardGetEmbedHtmlBody { - return CardGetEmbedHtmlBody( - token, - css, - expiration, - targetOrigin, - additionalBodyProperties, - ) - } - - internal fun getQueryParams(): Map> = additionalQueryParams - - internal fun getHeaders(): Map> = additionalHeaders - - @JsonDeserialize(builder = CardGetEmbedHtmlBody.Builder::class) - @NoAutoDetect - class CardGetEmbedHtmlBody - internal constructor( - private val token: String?, - private val css: String?, - private val expiration: OffsetDateTime?, - private val targetOrigin: String?, - private val additionalProperties: Map, - ) { - - private var hashCode: Int = 0 - - /** Globally unique identifier for the card to be displayed. */ - @JsonProperty("token") fun token(): String? = token - - /** - * A publicly available URI, so the white-labeled card element can be styled with the - * client's branding. - */ - @JsonProperty("css") fun css(): String? = css - - /** - * An RFC 3339 timestamp for when the request should expire. UTC time zone. - * - * If no timezone is specified, UTC will be used. If payload does not contain an expiration, - * the request will never expire. - * - * Using an `expiration` reduces the risk of a - * [replay attack](https://en.wikipedia.org/wiki/Replay_attack). Without supplying the - * `expiration`, in the event that a malicious user gets a copy of your request in transit, - * they will be able to obtain the response data indefinitely. - */ - @JsonProperty("expiration") fun expiration(): OffsetDateTime? = expiration - - /** - * Required if you want to post the element clicked to the parent iframe. - * - * If you supply this param, you can also capture click events in the parent iframe by - * adding an event listener. - */ - @JsonProperty("target_origin") fun targetOrigin(): String? = targetOrigin - - @JsonAnyGetter - @ExcludeMissing - fun _additionalProperties(): Map = additionalProperties - - fun toBuilder() = Builder().from(this) - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is CardGetEmbedHtmlBody && - this.token == other.token && - this.css == other.css && - this.expiration == other.expiration && - this.targetOrigin == other.targetOrigin && - this.additionalProperties == other.additionalProperties - } - - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = - Objects.hash( - token, - css, - expiration, - targetOrigin, - additionalProperties, - ) - } - return hashCode - } - - override fun toString() = - "CardGetEmbedHtmlBody{token=$token, css=$css, expiration=$expiration, targetOrigin=$targetOrigin, additionalProperties=$additionalProperties}" - - companion object { - - fun builder() = Builder() - } - - class Builder { - - private var token: String? = null - private var css: String? = null - private var expiration: OffsetDateTime? = null - private var targetOrigin: String? = null - private var additionalProperties: MutableMap = mutableMapOf() - - internal fun from(cardGetEmbedHtmlBody: CardGetEmbedHtmlBody) = apply { - this.token = cardGetEmbedHtmlBody.token - this.css = cardGetEmbedHtmlBody.css - this.expiration = cardGetEmbedHtmlBody.expiration - this.targetOrigin = cardGetEmbedHtmlBody.targetOrigin - additionalProperties(cardGetEmbedHtmlBody.additionalProperties) - } - - /** Globally unique identifier for the card to be displayed. */ - @JsonProperty("token") fun token(token: String) = apply { this.token = token } - - /** - * A publicly available URI, so the white-labeled card element can be styled with the - * client's branding. - */ - @JsonProperty("css") fun css(css: String) = apply { this.css = css } - - /** - * An RFC 3339 timestamp for when the request should expire. UTC time zone. - * - * If no timezone is specified, UTC will be used. If payload does not contain an - * expiration, the request will never expire. - * - * Using an `expiration` reduces the risk of a - * [replay attack](https://en.wikipedia.org/wiki/Replay_attack). Without supplying the - * `expiration`, in the event that a malicious user gets a copy of your request in - * transit, they will be able to obtain the response data indefinitely. - */ - @JsonProperty("expiration") - fun expiration(expiration: OffsetDateTime) = apply { this.expiration = expiration } - - /** - * Required if you want to post the element clicked to the parent iframe. - * - * If you supply this param, you can also capture click events in the parent iframe by - * adding an event listener. - */ - @JsonProperty("target_origin") - fun targetOrigin(targetOrigin: String) = apply { this.targetOrigin = targetOrigin } - - fun additionalProperties(additionalProperties: Map) = apply { - this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) - } - - @JsonAnySetter - fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) - } - - fun putAllAdditionalProperties(additionalProperties: Map) = apply { - this.additionalProperties.putAll(additionalProperties) - } - - fun build(): CardGetEmbedHtmlBody = - CardGetEmbedHtmlBody( - checkNotNull(token) { "`token` is required but was not set" }, - css, - expiration, - targetOrigin, - additionalProperties.toUnmodifiable(), - ) - } - } - - fun _additionalQueryParams(): Map> = additionalQueryParams - - fun _additionalHeaders(): Map> = additionalHeaders - - fun _additionalBodyProperties(): Map = additionalBodyProperties - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is CardGetEmbedHtmlParams && - this.token == other.token && - this.css == other.css && - this.expiration == other.expiration && - this.targetOrigin == other.targetOrigin && - this.additionalQueryParams == other.additionalQueryParams && - this.additionalHeaders == other.additionalHeaders && - this.additionalBodyProperties == other.additionalBodyProperties - } - - override fun hashCode(): Int { - return Objects.hash( - token, - css, - expiration, - targetOrigin, - additionalQueryParams, - additionalHeaders, - additionalBodyProperties, - ) - } - - override fun toString() = - "CardGetEmbedHtmlParams{token=$token, css=$css, expiration=$expiration, targetOrigin=$targetOrigin, additionalQueryParams=$additionalQueryParams, additionalHeaders=$additionalHeaders, additionalBodyProperties=$additionalBodyProperties}" - - fun toBuilder() = Builder().from(this) - - companion object { - - fun builder() = Builder() - } - - @NoAutoDetect - class Builder { - - private var token: String? = null - private var css: String? = null - private var expiration: OffsetDateTime? = null - private var targetOrigin: String? = null - private var additionalQueryParams: MutableMap> = mutableMapOf() - private var additionalHeaders: MutableMap> = mutableMapOf() - private var additionalBodyProperties: MutableMap = mutableMapOf() - - internal fun from(cardGetEmbedHtmlParams: CardGetEmbedHtmlParams) = apply { - this.token = cardGetEmbedHtmlParams.token - this.css = cardGetEmbedHtmlParams.css - this.expiration = cardGetEmbedHtmlParams.expiration - this.targetOrigin = cardGetEmbedHtmlParams.targetOrigin - additionalQueryParams(cardGetEmbedHtmlParams.additionalQueryParams) - additionalHeaders(cardGetEmbedHtmlParams.additionalHeaders) - additionalBodyProperties(cardGetEmbedHtmlParams.additionalBodyProperties) - } - - /** Globally unique identifier for the card to be displayed. */ - fun token(token: String) = apply { this.token = token } - - /** - * A publicly available URI, so the white-labeled card element can be styled with the - * client's branding. - */ - fun css(css: String) = apply { this.css = css } - - /** - * An RFC 3339 timestamp for when the request should expire. UTC time zone. - * - * If no timezone is specified, UTC will be used. If payload does not contain an expiration, - * the request will never expire. - * - * Using an `expiration` reduces the risk of a - * [replay attack](https://en.wikipedia.org/wiki/Replay_attack). Without supplying the - * `expiration`, in the event that a malicious user gets a copy of your request in transit, - * they will be able to obtain the response data indefinitely. - */ - fun expiration(expiration: OffsetDateTime) = apply { this.expiration = expiration } - - /** - * Required if you want to post the element clicked to the parent iframe. - * - * If you supply this param, you can also capture click events in the parent iframe by - * adding an event listener. - */ - fun targetOrigin(targetOrigin: String) = apply { this.targetOrigin = targetOrigin } - - fun additionalQueryParams(additionalQueryParams: Map>) = apply { - this.additionalQueryParams.clear() - putAllQueryParams(additionalQueryParams) - } - - fun putQueryParam(name: String, value: String) = apply { - this.additionalQueryParams.getOrPut(name) { mutableListOf() }.add(value) - } - - fun putQueryParams(name: String, values: Iterable) = apply { - this.additionalQueryParams.getOrPut(name) { mutableListOf() }.addAll(values) - } - - fun putAllQueryParams(additionalQueryParams: Map>) = apply { - additionalQueryParams.forEach(this::putQueryParams) - } - - fun removeQueryParam(name: String) = apply { - this.additionalQueryParams.put(name, mutableListOf()) - } - - fun additionalHeaders(additionalHeaders: Map>) = apply { - this.additionalHeaders.clear() - putAllHeaders(additionalHeaders) - } - - fun putHeader(name: String, value: String) = apply { - this.additionalHeaders.getOrPut(name) { mutableListOf() }.add(value) - } - - fun putHeaders(name: String, values: Iterable) = apply { - this.additionalHeaders.getOrPut(name) { mutableListOf() }.addAll(values) - } - - fun putAllHeaders(additionalHeaders: Map>) = apply { - additionalHeaders.forEach(this::putHeaders) - } - - fun removeHeader(name: String) = apply { this.additionalHeaders.put(name, mutableListOf()) } - - fun additionalBodyProperties(additionalBodyProperties: Map) = apply { - this.additionalBodyProperties.clear() - this.additionalBodyProperties.putAll(additionalBodyProperties) - } - - fun putAdditionalBodyProperty(key: String, value: JsonValue) = apply { - this.additionalBodyProperties.put(key, value) - } - - fun putAllAdditionalBodyProperties(additionalBodyProperties: Map) = - apply { - this.additionalBodyProperties.putAll(additionalBodyProperties) - } - - fun build(): CardGetEmbedHtmlParams = - CardGetEmbedHtmlParams( - checkNotNull(token) { "`token` is required but was not set" }, - css, - expiration, - targetOrigin, - additionalQueryParams.mapValues { it.value.toUnmodifiable() }.toUnmodifiable(), - additionalHeaders.mapValues { it.value.toUnmodifiable() }.toUnmodifiable(), - additionalBodyProperties.toUnmodifiable(), - ) - } -} diff --git a/lithic-kotlin-core/src/main/kotlin/com/lithic/api/models/CardGetEmbedUrlParams.kt b/lithic-kotlin-core/src/main/kotlin/com/lithic/api/models/CardGetEmbedUrlParams.kt deleted file mode 100644 index e6b9720e..00000000 --- a/lithic-kotlin-core/src/main/kotlin/com/lithic/api/models/CardGetEmbedUrlParams.kt +++ /dev/null @@ -1,366 +0,0 @@ -// File generated from our OpenAPI spec by Stainless. - -package com.lithic.api.models - -import com.fasterxml.jackson.annotation.JsonAnyGetter -import com.fasterxml.jackson.annotation.JsonAnySetter -import com.fasterxml.jackson.annotation.JsonProperty -import com.fasterxml.jackson.databind.annotation.JsonDeserialize -import com.lithic.api.core.ExcludeMissing -import com.lithic.api.core.JsonValue -import com.lithic.api.core.NoAutoDetect -import com.lithic.api.core.toUnmodifiable -import com.lithic.api.models.* -import java.time.OffsetDateTime -import java.util.Objects - -class CardGetEmbedUrlParams -constructor( - private val token: String, - private val css: String?, - private val expiration: OffsetDateTime?, - private val targetOrigin: String?, - private val additionalQueryParams: Map>, - private val additionalHeaders: Map>, - private val additionalBodyProperties: Map, -) { - - fun token(): String = token - - fun css(): String? = css - - fun expiration(): OffsetDateTime? = expiration - - fun targetOrigin(): String? = targetOrigin - - internal fun getBody(): CardGetEmbedUrlBody { - return CardGetEmbedUrlBody( - token, - css, - expiration, - targetOrigin, - additionalBodyProperties, - ) - } - - internal fun getQueryParams(): Map> = additionalQueryParams - - internal fun getHeaders(): Map> = additionalHeaders - - @JsonDeserialize(builder = CardGetEmbedUrlBody.Builder::class) - @NoAutoDetect - class CardGetEmbedUrlBody - internal constructor( - private val token: String?, - private val css: String?, - private val expiration: OffsetDateTime?, - private val targetOrigin: String?, - private val additionalProperties: Map, - ) { - - private var hashCode: Int = 0 - - /** Globally unique identifier for the card to be displayed. */ - @JsonProperty("token") fun token(): String? = token - - /** - * A publicly available URI, so the white-labeled card element can be styled with the - * client's branding. - */ - @JsonProperty("css") fun css(): String? = css - - /** - * An RFC 3339 timestamp for when the request should expire. UTC time zone. - * - * If no timezone is specified, UTC will be used. If payload does not contain an expiration, - * the request will never expire. - * - * Using an `expiration` reduces the risk of a - * [replay attack](https://en.wikipedia.org/wiki/Replay_attack). Without supplying the - * `expiration`, in the event that a malicious user gets a copy of your request in transit, - * they will be able to obtain the response data indefinitely. - */ - @JsonProperty("expiration") fun expiration(): OffsetDateTime? = expiration - - /** - * Required if you want to post the element clicked to the parent iframe. - * - * If you supply this param, you can also capture click events in the parent iframe by - * adding an event listener. - */ - @JsonProperty("target_origin") fun targetOrigin(): String? = targetOrigin - - @JsonAnyGetter - @ExcludeMissing - fun _additionalProperties(): Map = additionalProperties - - fun toBuilder() = Builder().from(this) - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is CardGetEmbedUrlBody && - this.token == other.token && - this.css == other.css && - this.expiration == other.expiration && - this.targetOrigin == other.targetOrigin && - this.additionalProperties == other.additionalProperties - } - - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = - Objects.hash( - token, - css, - expiration, - targetOrigin, - additionalProperties, - ) - } - return hashCode - } - - override fun toString() = - "CardGetEmbedUrlBody{token=$token, css=$css, expiration=$expiration, targetOrigin=$targetOrigin, additionalProperties=$additionalProperties}" - - companion object { - - fun builder() = Builder() - } - - class Builder { - - private var token: String? = null - private var css: String? = null - private var expiration: OffsetDateTime? = null - private var targetOrigin: String? = null - private var additionalProperties: MutableMap = mutableMapOf() - - internal fun from(cardGetEmbedUrlBody: CardGetEmbedUrlBody) = apply { - this.token = cardGetEmbedUrlBody.token - this.css = cardGetEmbedUrlBody.css - this.expiration = cardGetEmbedUrlBody.expiration - this.targetOrigin = cardGetEmbedUrlBody.targetOrigin - additionalProperties(cardGetEmbedUrlBody.additionalProperties) - } - - /** Globally unique identifier for the card to be displayed. */ - @JsonProperty("token") fun token(token: String) = apply { this.token = token } - - /** - * A publicly available URI, so the white-labeled card element can be styled with the - * client's branding. - */ - @JsonProperty("css") fun css(css: String) = apply { this.css = css } - - /** - * An RFC 3339 timestamp for when the request should expire. UTC time zone. - * - * If no timezone is specified, UTC will be used. If payload does not contain an - * expiration, the request will never expire. - * - * Using an `expiration` reduces the risk of a - * [replay attack](https://en.wikipedia.org/wiki/Replay_attack). Without supplying the - * `expiration`, in the event that a malicious user gets a copy of your request in - * transit, they will be able to obtain the response data indefinitely. - */ - @JsonProperty("expiration") - fun expiration(expiration: OffsetDateTime) = apply { this.expiration = expiration } - - /** - * Required if you want to post the element clicked to the parent iframe. - * - * If you supply this param, you can also capture click events in the parent iframe by - * adding an event listener. - */ - @JsonProperty("target_origin") - fun targetOrigin(targetOrigin: String) = apply { this.targetOrigin = targetOrigin } - - fun additionalProperties(additionalProperties: Map) = apply { - this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) - } - - @JsonAnySetter - fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) - } - - fun putAllAdditionalProperties(additionalProperties: Map) = apply { - this.additionalProperties.putAll(additionalProperties) - } - - fun build(): CardGetEmbedUrlBody = - CardGetEmbedUrlBody( - checkNotNull(token) { "`token` is required but was not set" }, - css, - expiration, - targetOrigin, - additionalProperties.toUnmodifiable(), - ) - } - } - - fun _additionalQueryParams(): Map> = additionalQueryParams - - fun _additionalHeaders(): Map> = additionalHeaders - - fun _additionalBodyProperties(): Map = additionalBodyProperties - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is CardGetEmbedUrlParams && - this.token == other.token && - this.css == other.css && - this.expiration == other.expiration && - this.targetOrigin == other.targetOrigin && - this.additionalQueryParams == other.additionalQueryParams && - this.additionalHeaders == other.additionalHeaders && - this.additionalBodyProperties == other.additionalBodyProperties - } - - override fun hashCode(): Int { - return Objects.hash( - token, - css, - expiration, - targetOrigin, - additionalQueryParams, - additionalHeaders, - additionalBodyProperties, - ) - } - - override fun toString() = - "CardGetEmbedUrlParams{token=$token, css=$css, expiration=$expiration, targetOrigin=$targetOrigin, additionalQueryParams=$additionalQueryParams, additionalHeaders=$additionalHeaders, additionalBodyProperties=$additionalBodyProperties}" - - fun toBuilder() = Builder().from(this) - - companion object { - - fun builder() = Builder() - } - - @NoAutoDetect - class Builder { - - private var token: String? = null - private var css: String? = null - private var expiration: OffsetDateTime? = null - private var targetOrigin: String? = null - private var additionalQueryParams: MutableMap> = mutableMapOf() - private var additionalHeaders: MutableMap> = mutableMapOf() - private var additionalBodyProperties: MutableMap = mutableMapOf() - - internal fun from(cardGetEmbedUrlParams: CardGetEmbedUrlParams) = apply { - this.token = cardGetEmbedUrlParams.token - this.css = cardGetEmbedUrlParams.css - this.expiration = cardGetEmbedUrlParams.expiration - this.targetOrigin = cardGetEmbedUrlParams.targetOrigin - additionalQueryParams(cardGetEmbedUrlParams.additionalQueryParams) - additionalHeaders(cardGetEmbedUrlParams.additionalHeaders) - additionalBodyProperties(cardGetEmbedUrlParams.additionalBodyProperties) - } - - /** Globally unique identifier for the card to be displayed. */ - fun token(token: String) = apply { this.token = token } - - /** - * A publicly available URI, so the white-labeled card element can be styled with the - * client's branding. - */ - fun css(css: String) = apply { this.css = css } - - /** - * An RFC 3339 timestamp for when the request should expire. UTC time zone. - * - * If no timezone is specified, UTC will be used. If payload does not contain an expiration, - * the request will never expire. - * - * Using an `expiration` reduces the risk of a - * [replay attack](https://en.wikipedia.org/wiki/Replay_attack). Without supplying the - * `expiration`, in the event that a malicious user gets a copy of your request in transit, - * they will be able to obtain the response data indefinitely. - */ - fun expiration(expiration: OffsetDateTime) = apply { this.expiration = expiration } - - /** - * Required if you want to post the element clicked to the parent iframe. - * - * If you supply this param, you can also capture click events in the parent iframe by - * adding an event listener. - */ - fun targetOrigin(targetOrigin: String) = apply { this.targetOrigin = targetOrigin } - - fun additionalQueryParams(additionalQueryParams: Map>) = apply { - this.additionalQueryParams.clear() - putAllQueryParams(additionalQueryParams) - } - - fun putQueryParam(name: String, value: String) = apply { - this.additionalQueryParams.getOrPut(name) { mutableListOf() }.add(value) - } - - fun putQueryParams(name: String, values: Iterable) = apply { - this.additionalQueryParams.getOrPut(name) { mutableListOf() }.addAll(values) - } - - fun putAllQueryParams(additionalQueryParams: Map>) = apply { - additionalQueryParams.forEach(this::putQueryParams) - } - - fun removeQueryParam(name: String) = apply { - this.additionalQueryParams.put(name, mutableListOf()) - } - - fun additionalHeaders(additionalHeaders: Map>) = apply { - this.additionalHeaders.clear() - putAllHeaders(additionalHeaders) - } - - fun putHeader(name: String, value: String) = apply { - this.additionalHeaders.getOrPut(name) { mutableListOf() }.add(value) - } - - fun putHeaders(name: String, values: Iterable) = apply { - this.additionalHeaders.getOrPut(name) { mutableListOf() }.addAll(values) - } - - fun putAllHeaders(additionalHeaders: Map>) = apply { - additionalHeaders.forEach(this::putHeaders) - } - - fun removeHeader(name: String) = apply { this.additionalHeaders.put(name, mutableListOf()) } - - fun additionalBodyProperties(additionalBodyProperties: Map) = apply { - this.additionalBodyProperties.clear() - this.additionalBodyProperties.putAll(additionalBodyProperties) - } - - fun putAdditionalBodyProperty(key: String, value: JsonValue) = apply { - this.additionalBodyProperties.put(key, value) - } - - fun putAllAdditionalBodyProperties(additionalBodyProperties: Map) = - apply { - this.additionalBodyProperties.putAll(additionalBodyProperties) - } - - fun build(): CardGetEmbedUrlParams = - CardGetEmbedUrlParams( - checkNotNull(token) { "`token` is required but was not set" }, - css, - expiration, - targetOrigin, - additionalQueryParams.mapValues { it.value.toUnmodifiable() }.toUnmodifiable(), - additionalHeaders.mapValues { it.value.toUnmodifiable() }.toUnmodifiable(), - additionalBodyProperties.toUnmodifiable(), - ) - } -} diff --git a/lithic-kotlin-core/src/main/kotlin/com/lithic/api/services/async/CardServiceAsync.kt b/lithic-kotlin-core/src/main/kotlin/com/lithic/api/services/async/CardServiceAsync.kt index 75781e6b..09b8834d 100644 --- a/lithic-kotlin-core/src/main/kotlin/com/lithic/api/services/async/CardServiceAsync.kt +++ b/lithic-kotlin-core/src/main/kotlin/com/lithic/api/services/async/CardServiceAsync.kt @@ -8,8 +8,6 @@ import com.lithic.api.core.RequestOptions import com.lithic.api.models.Card import com.lithic.api.models.CardCreateParams import com.lithic.api.models.CardEmbedParams -import com.lithic.api.models.CardGetEmbedHtmlParams -import com.lithic.api.models.CardGetEmbedUrlParams import com.lithic.api.models.CardListPageAsync import com.lithic.api.models.CardListParams import com.lithic.api.models.CardProvisionParams @@ -149,14 +147,4 @@ interface CardServiceAsync { params: CardSearchByPanParams, requestOptions: RequestOptions = RequestOptions.none() ): Card - - suspend fun getEmbedHtml( - params: CardGetEmbedHtmlParams, - requestOptions: RequestOptions = RequestOptions.none() - ): String - - suspend fun getEmbedUrl( - params: CardGetEmbedUrlParams, - requestOptions: RequestOptions = RequestOptions.none() - ): String } diff --git a/lithic-kotlin-core/src/main/kotlin/com/lithic/api/services/async/CardServiceAsyncImpl.kt b/lithic-kotlin-core/src/main/kotlin/com/lithic/api/services/async/CardServiceAsyncImpl.kt index 97b18000..6042a023 100644 --- a/lithic-kotlin-core/src/main/kotlin/com/lithic/api/services/async/CardServiceAsyncImpl.kt +++ b/lithic-kotlin-core/src/main/kotlin/com/lithic/api/services/async/CardServiceAsyncImpl.kt @@ -11,8 +11,6 @@ import com.lithic.api.errors.LithicError import com.lithic.api.models.Card import com.lithic.api.models.CardCreateParams import com.lithic.api.models.CardEmbedParams -import com.lithic.api.models.CardGetEmbedHtmlParams -import com.lithic.api.models.CardGetEmbedUrlParams import com.lithic.api.models.CardListPageAsync import com.lithic.api.models.CardListParams import com.lithic.api.models.CardProvisionParams @@ -35,11 +33,6 @@ import com.lithic.api.services.json import com.lithic.api.services.jsonHandler import com.lithic.api.services.stringHandler import com.lithic.api.services.withErrorHandler -import java.net.URI -import java.util.Base64 -import javax.crypto.Mac -import javax.crypto.spec.SecretKeySpec -import org.apache.hc.core5.net.URIBuilder class CardServiceAsyncImpl constructor( @@ -376,52 +369,4 @@ constructor( } } } - - override suspend fun getEmbedHtml( - params: CardGetEmbedHtmlParams, - requestOptions: RequestOptions - ): String { - val embed_request = - Base64.getEncoder() - .encodeToString(clientOptions.jsonMapper.writeValueAsBytes(params.getBody())) - - val mac: Mac = Mac.getInstance("HmacSHA256") - mac.init(SecretKeySpec(clientOptions.apiKey.toByteArray(), "HmacSHA256")) - val embed_request_hmac = - Base64.getEncoder().encodeToString(mac.doFinal(embed_request.toByteArray())) - - val request = - HttpRequest.builder() - .method(HttpMethod.GET) - .addPathSegments("embed", "card") - .putQueryParam("embed_request", embed_request) - .putQueryParam("hmac", embed_request_hmac) - .putAllHeaders(clientOptions.headers) - .putAllHeaders(params.getHeaders()) - .putHeader("Accept", "text/html") - .build() - return clientOptions.httpClient.executeAsync(request).let { response -> - response.let { embedHandler.handle(it) } - } - } - - override suspend fun getEmbedUrl( - params: CardGetEmbedUrlParams, - requestOptions: RequestOptions - ): String { - val embed_request = - Base64.getEncoder() - .encodeToString(clientOptions.jsonMapper.writeValueAsBytes(params.getBody())) - - val mac: Mac = Mac.getInstance("HmacSHA256") - mac.init(SecretKeySpec(clientOptions.apiKey.toByteArray(), "HmacSHA256")) - val embed_request_hmac = - Base64.getEncoder().encodeToString(mac.doFinal(embed_request.toByteArray())) - - return URIBuilder(URI.create(clientOptions.baseUrl)) - .appendPathSegments("embed", "card") - .addParameter("embed_request", embed_request) - .addParameter("hmac", embed_request_hmac) - .toString() - } } diff --git a/lithic-kotlin-core/src/main/kotlin/com/lithic/api/services/async/DisputeServiceAsync.kt b/lithic-kotlin-core/src/main/kotlin/com/lithic/api/services/async/DisputeServiceAsync.kt index bb5f89ec..4580d724 100644 --- a/lithic-kotlin-core/src/main/kotlin/com/lithic/api/services/async/DisputeServiceAsync.kt +++ b/lithic-kotlin-core/src/main/kotlin/com/lithic/api/services/async/DisputeServiceAsync.kt @@ -83,6 +83,4 @@ interface DisputeServiceAsync { params: DisputeRetrieveEvidenceParams, requestOptions: RequestOptions = RequestOptions.none() ): DisputeEvidence - - suspend fun uploadEvidence(disputeToken: String, file: ByteArray) } diff --git a/lithic-kotlin-core/src/main/kotlin/com/lithic/api/services/async/DisputeServiceAsyncImpl.kt b/lithic-kotlin-core/src/main/kotlin/com/lithic/api/services/async/DisputeServiceAsyncImpl.kt index 7e0c5cf3..a688e0c6 100644 --- a/lithic-kotlin-core/src/main/kotlin/com/lithic/api/services/async/DisputeServiceAsyncImpl.kt +++ b/lithic-kotlin-core/src/main/kotlin/com/lithic/api/services/async/DisputeServiceAsyncImpl.kt @@ -8,7 +8,6 @@ import com.lithic.api.core.http.HttpMethod import com.lithic.api.core.http.HttpRequest import com.lithic.api.core.http.HttpResponse.Handler import com.lithic.api.errors.LithicError -import com.lithic.api.errors.LithicInvalidDataException import com.lithic.api.models.Dispute import com.lithic.api.models.DisputeCreateParams import com.lithic.api.models.DisputeDeleteEvidenceParams @@ -22,11 +21,9 @@ import com.lithic.api.models.DisputeListParams import com.lithic.api.models.DisputeRetrieveEvidenceParams import com.lithic.api.models.DisputeRetrieveParams import com.lithic.api.models.DisputeUpdateParams -import com.lithic.api.services.emptyHandler import com.lithic.api.services.errorHandler import com.lithic.api.services.json import com.lithic.api.services.jsonHandler -import com.lithic.api.services.multipartFormData import com.lithic.api.services.withErrorHandler class DisputeServiceAsyncImpl @@ -306,24 +303,4 @@ constructor( } } } - - override suspend fun uploadEvidence(disputeToken: String, file: ByteArray) { - val initiateParams = - DisputeInitiateEvidenceUploadParams.builder().disputeToken(disputeToken).build() - val initiateResponse = initiateEvidenceUpload(initiateParams) - - val uploadUrl = - initiateResponse.uploadUrl() - ?: throw LithicInvalidDataException("Missing 'upload_url' from response payload") - - val uploadRequest = - HttpRequest.builder() - .method(HttpMethod.PUT) - .url(uploadUrl) - .body(multipartFormData(mapOf("file" to file))) - .build() - clientOptions.httpClient.executeAsync(uploadRequest).let { response -> - response.let { emptyHandler().handle(it) } - } - } } diff --git a/lithic-kotlin-core/src/main/kotlin/com/lithic/api/services/async/EventServiceAsync.kt b/lithic-kotlin-core/src/main/kotlin/com/lithic/api/services/async/EventServiceAsync.kt index 0c9ec254..de562443 100644 --- a/lithic-kotlin-core/src/main/kotlin/com/lithic/api/services/async/EventServiceAsync.kt +++ b/lithic-kotlin-core/src/main/kotlin/com/lithic/api/services/async/EventServiceAsync.kt @@ -4,7 +4,6 @@ package com.lithic.api.services.async -import com.lithic.api.core.JsonValue import com.lithic.api.core.RequestOptions import com.lithic.api.models.Event import com.lithic.api.models.EventListAttemptsPageAsync @@ -35,6 +34,4 @@ interface EventServiceAsync { params: EventListAttemptsParams, requestOptions: RequestOptions = RequestOptions.none() ): EventListAttemptsPageAsync - - suspend fun resend(eventToken: String, eventSubscriptionToken: String, body: JsonValue) } diff --git a/lithic-kotlin-core/src/main/kotlin/com/lithic/api/services/async/EventServiceAsyncImpl.kt b/lithic-kotlin-core/src/main/kotlin/com/lithic/api/services/async/EventServiceAsyncImpl.kt index da4d04fa..01a19b78 100644 --- a/lithic-kotlin-core/src/main/kotlin/com/lithic/api/services/async/EventServiceAsyncImpl.kt +++ b/lithic-kotlin-core/src/main/kotlin/com/lithic/api/services/async/EventServiceAsyncImpl.kt @@ -3,7 +3,6 @@ package com.lithic.api.services.async import com.lithic.api.core.ClientOptions -import com.lithic.api.core.JsonValue import com.lithic.api.core.RequestOptions import com.lithic.api.core.http.HttpMethod import com.lithic.api.core.http.HttpRequest @@ -17,9 +16,7 @@ import com.lithic.api.models.EventListParams import com.lithic.api.models.EventRetrieveParams import com.lithic.api.services.async.events.SubscriptionServiceAsync import com.lithic.api.services.async.events.SubscriptionServiceAsyncImpl -import com.lithic.api.services.emptyHandler import com.lithic.api.services.errorHandler -import com.lithic.api.services.json import com.lithic.api.services.jsonHandler import com.lithic.api.services.withErrorHandler @@ -120,26 +117,4 @@ constructor( .let { EventListAttemptsPageAsync.of(this, params, it) } } } - - override suspend fun resend( - eventToken: String, - eventSubscriptionToken: String, - body: JsonValue - ) { - val request = - HttpRequest.builder() - .method(HttpMethod.POST) - .addPathSegments( - "events", - eventToken, - "event_subscriptions", - eventSubscriptionToken, - "resend" - ) - .body(json(clientOptions.jsonMapper, body)) - .build() - clientOptions.httpClient.executeAsync(request).let { response -> - response.let { emptyHandler().handle(it) } - } - } } diff --git a/lithic-kotlin-core/src/main/kotlin/com/lithic/api/services/async/WebhookServiceAsync.kt b/lithic-kotlin-core/src/main/kotlin/com/lithic/api/services/async/WebhookServiceAsync.kt deleted file mode 100644 index 01bbf20d..00000000 --- a/lithic-kotlin-core/src/main/kotlin/com/lithic/api/services/async/WebhookServiceAsync.kt +++ /dev/null @@ -1,23 +0,0 @@ -// File generated from our OpenAPI spec by Stainless. - -@file:Suppress("OVERLOADS_INTERFACE") // See https://youtrack.jetbrains.com/issue/KT-36102 - -package com.lithic.api.services.async - -import com.google.common.collect.ListMultimap -import com.lithic.api.core.JsonValue - -interface WebhookServiceAsync { - - suspend fun unwrap( - payload: String, - headers: ListMultimap, - secret: String? - ): JsonValue - - suspend fun verifySignature( - payload: String, - headers: ListMultimap, - secret: String? - ) -} diff --git a/lithic-kotlin-core/src/main/kotlin/com/lithic/api/services/async/WebhookServiceAsyncImpl.kt b/lithic-kotlin-core/src/main/kotlin/com/lithic/api/services/async/WebhookServiceAsyncImpl.kt deleted file mode 100644 index 0d10b7c9..00000000 --- a/lithic-kotlin-core/src/main/kotlin/com/lithic/api/services/async/WebhookServiceAsyncImpl.kt +++ /dev/null @@ -1,101 +0,0 @@ -// File generated from our OpenAPI spec by Stainless. - -package com.lithic.api.services.async - -import com.fasterxml.jackson.core.JsonProcessingException -import com.google.common.collect.ListMultimap -import com.lithic.api.core.ClientOptions -import com.lithic.api.core.JsonValue -import com.lithic.api.core.getRequiredHeader -import com.lithic.api.core.http.HttpResponse.Handler -import com.lithic.api.errors.LithicError -import com.lithic.api.errors.LithicException -import com.lithic.api.services.errorHandler -import java.security.MessageDigest -import java.time.Duration -import java.time.Instant -import java.util.Base64 -import javax.crypto.Mac -import javax.crypto.spec.SecretKeySpec - -class WebhookServiceAsyncImpl -constructor( - private val clientOptions: ClientOptions, -) : WebhookServiceAsync { - - private val errorHandler: Handler = errorHandler(clientOptions.jsonMapper) - - override suspend fun unwrap( - payload: String, - headers: ListMultimap, - secret: String? - ): JsonValue { - verifySignature(payload, headers, secret) - return try { - clientOptions.jsonMapper.readValue(payload, JsonValue::class.java) - } catch (e: JsonProcessingException) { - throw LithicException("Invalid event payload", e) - } - } - - override suspend fun verifySignature( - payload: String, - headers: ListMultimap, - secret: String? - ) { - val webhookSecret = - secret - ?: clientOptions.webhookSecret - ?: throw LithicException( - "The webhook secret must either be set using the env var, LITHIC_WEBHOOK_SECRET, on the client class, or passed to this method" - ) - - val whsecret = - try { - Base64.getDecoder().decode(webhookSecret.removePrefix("whsec_")) - } catch (e: RuntimeException) { - throw LithicException("Invalid webhook secret") - } - - val msgId = headers.getRequiredHeader("webhook-id") - val msgSignature = headers.getRequiredHeader("webhook-signature") - val msgTimestamp = headers.getRequiredHeader("webhook-timestamp") - - val timestamp = - try { - Instant.ofEpochSecond(msgTimestamp.toLong()) - } catch (e: RuntimeException) { - throw LithicException("Invalid signature headers", e) - } - val now = Instant.now(clientOptions.clock) - - if (timestamp.isBefore(now.minus(Duration.ofMinutes(5)))) { - throw LithicException("Webhook timestamp too old") - } - if (timestamp.isAfter(now.plus(Duration.ofMinutes(5)))) { - throw LithicException("Webhook timestamp too new") - } - - val mac = Mac.getInstance("HmacSHA256") - mac.init(SecretKeySpec(whsecret, "HmacSHA256")) - val expectedSignature = - mac.doFinal("$msgId.${timestamp.epochSecond}.$payload".toByteArray()) - - msgSignature.splitToSequence(" ").forEach { - val parts = it.split(",") - if (parts.size != 2) { - return@forEach - } - - if (parts[0] != "v1") { - return@forEach - } - - if (MessageDigest.isEqual(Base64.getDecoder().decode(parts[1]), expectedSignature)) { - return - } - } - - throw LithicException("None of the given webhook signatures match the expected signature") - } -} diff --git a/lithic-kotlin-core/src/main/kotlin/com/lithic/api/services/blocking/CardService.kt b/lithic-kotlin-core/src/main/kotlin/com/lithic/api/services/blocking/CardService.kt index b6de0318..3ebb7af3 100644 --- a/lithic-kotlin-core/src/main/kotlin/com/lithic/api/services/blocking/CardService.kt +++ b/lithic-kotlin-core/src/main/kotlin/com/lithic/api/services/blocking/CardService.kt @@ -8,8 +8,6 @@ import com.lithic.api.core.RequestOptions import com.lithic.api.models.Card import com.lithic.api.models.CardCreateParams import com.lithic.api.models.CardEmbedParams -import com.lithic.api.models.CardGetEmbedHtmlParams -import com.lithic.api.models.CardGetEmbedUrlParams import com.lithic.api.models.CardListPage import com.lithic.api.models.CardListParams import com.lithic.api.models.CardProvisionParams @@ -146,14 +144,4 @@ interface CardService { params: CardSearchByPanParams, requestOptions: RequestOptions = RequestOptions.none() ): Card - - fun getEmbedHtml( - params: CardGetEmbedHtmlParams, - requestOptions: RequestOptions = RequestOptions.none() - ): String - - fun getEmbedUrl( - params: CardGetEmbedUrlParams, - requestOptions: RequestOptions = RequestOptions.none() - ): String } diff --git a/lithic-kotlin-core/src/main/kotlin/com/lithic/api/services/blocking/CardServiceImpl.kt b/lithic-kotlin-core/src/main/kotlin/com/lithic/api/services/blocking/CardServiceImpl.kt index 90e8fb97..01be0276 100644 --- a/lithic-kotlin-core/src/main/kotlin/com/lithic/api/services/blocking/CardServiceImpl.kt +++ b/lithic-kotlin-core/src/main/kotlin/com/lithic/api/services/blocking/CardServiceImpl.kt @@ -11,8 +11,6 @@ import com.lithic.api.errors.LithicError import com.lithic.api.models.Card import com.lithic.api.models.CardCreateParams import com.lithic.api.models.CardEmbedParams -import com.lithic.api.models.CardGetEmbedHtmlParams -import com.lithic.api.models.CardGetEmbedUrlParams import com.lithic.api.models.CardListPage import com.lithic.api.models.CardListParams import com.lithic.api.models.CardProvisionParams @@ -35,11 +33,6 @@ import com.lithic.api.services.json import com.lithic.api.services.jsonHandler import com.lithic.api.services.stringHandler import com.lithic.api.services.withErrorHandler -import java.net.URI -import java.util.Base64 -import javax.crypto.Mac -import javax.crypto.spec.SecretKeySpec -import org.apache.hc.core5.net.URIBuilder class CardServiceImpl constructor( @@ -366,52 +359,4 @@ constructor( } } } - - override fun getEmbedHtml( - params: CardGetEmbedHtmlParams, - requestOptions: RequestOptions - ): String { - val embed_request = - Base64.getEncoder() - .encodeToString(clientOptions.jsonMapper.writeValueAsBytes(params.getBody())) - - val mac: Mac = Mac.getInstance("HmacSHA256") - mac.init(SecretKeySpec(clientOptions.apiKey.toByteArray(), "HmacSHA256")) - val embed_request_hmac = - Base64.getEncoder().encodeToString(mac.doFinal(embed_request.toByteArray())) - - val request = - HttpRequest.builder() - .method(HttpMethod.GET) - .addPathSegments("embed", "card") - .putQueryParam("embed_request", embed_request) - .putQueryParam("hmac", embed_request_hmac) - .putAllHeaders(clientOptions.headers) - .putAllHeaders(params.getHeaders()) - .putHeader("Accept", "text/html") - .build() - return clientOptions.httpClient.execute(request).let { response -> - response.let { embedHandler.handle(it) } - } - } - - override fun getEmbedUrl( - params: CardGetEmbedUrlParams, - requestOptions: RequestOptions - ): String { - val embed_request = - Base64.getEncoder() - .encodeToString(clientOptions.jsonMapper.writeValueAsBytes(params.getBody())) - - val mac: Mac = Mac.getInstance("HmacSHA256") - mac.init(SecretKeySpec(clientOptions.apiKey.toByteArray(), "HmacSHA256")) - val embed_request_hmac = - Base64.getEncoder().encodeToString(mac.doFinal(embed_request.toByteArray())) - - return URIBuilder(URI.create(clientOptions.baseUrl)) - .appendPathSegments("embed", "card") - .addParameter("embed_request", embed_request) - .addParameter("hmac", embed_request_hmac) - .toString() - } } diff --git a/lithic-kotlin-core/src/main/kotlin/com/lithic/api/services/blocking/DisputeService.kt b/lithic-kotlin-core/src/main/kotlin/com/lithic/api/services/blocking/DisputeService.kt index 0b947b78..a03447f1 100644 --- a/lithic-kotlin-core/src/main/kotlin/com/lithic/api/services/blocking/DisputeService.kt +++ b/lithic-kotlin-core/src/main/kotlin/com/lithic/api/services/blocking/DisputeService.kt @@ -83,6 +83,4 @@ interface DisputeService { params: DisputeRetrieveEvidenceParams, requestOptions: RequestOptions = RequestOptions.none() ): DisputeEvidence - - fun uploadEvidence(disputeToken: String, file: ByteArray) } diff --git a/lithic-kotlin-core/src/main/kotlin/com/lithic/api/services/blocking/DisputeServiceImpl.kt b/lithic-kotlin-core/src/main/kotlin/com/lithic/api/services/blocking/DisputeServiceImpl.kt index 69aa16de..f7bc8aaf 100644 --- a/lithic-kotlin-core/src/main/kotlin/com/lithic/api/services/blocking/DisputeServiceImpl.kt +++ b/lithic-kotlin-core/src/main/kotlin/com/lithic/api/services/blocking/DisputeServiceImpl.kt @@ -8,7 +8,6 @@ import com.lithic.api.core.http.HttpMethod import com.lithic.api.core.http.HttpRequest import com.lithic.api.core.http.HttpResponse.Handler import com.lithic.api.errors.LithicError -import com.lithic.api.errors.LithicInvalidDataException import com.lithic.api.models.Dispute import com.lithic.api.models.DisputeCreateParams import com.lithic.api.models.DisputeDeleteEvidenceParams @@ -22,11 +21,9 @@ import com.lithic.api.models.DisputeListParams import com.lithic.api.models.DisputeRetrieveEvidenceParams import com.lithic.api.models.DisputeRetrieveParams import com.lithic.api.models.DisputeUpdateParams -import com.lithic.api.services.emptyHandler import com.lithic.api.services.errorHandler import com.lithic.api.services.json import com.lithic.api.services.jsonHandler -import com.lithic.api.services.multipartFormData import com.lithic.api.services.withErrorHandler class DisputeServiceImpl @@ -291,24 +288,4 @@ constructor( } } } - - override fun uploadEvidence(disputeToken: String, file: ByteArray) { - val initiateParams = - DisputeInitiateEvidenceUploadParams.builder().disputeToken(disputeToken).build() - val initiateResponse = initiateEvidenceUpload(initiateParams) - - val uploadUrl = - initiateResponse.uploadUrl() - ?: throw LithicInvalidDataException("Missing 'upload_url' from response payload") - - val uploadRequest = - HttpRequest.builder() - .method(HttpMethod.PUT) - .url(uploadUrl) - .body(multipartFormData(mapOf("file" to file))) - .build() - clientOptions.httpClient.execute(uploadRequest).let { response -> - response.let { emptyHandler().handle(it) } - } - } } diff --git a/lithic-kotlin-core/src/main/kotlin/com/lithic/api/services/blocking/EventService.kt b/lithic-kotlin-core/src/main/kotlin/com/lithic/api/services/blocking/EventService.kt index 4c05cadf..d74e3628 100644 --- a/lithic-kotlin-core/src/main/kotlin/com/lithic/api/services/blocking/EventService.kt +++ b/lithic-kotlin-core/src/main/kotlin/com/lithic/api/services/blocking/EventService.kt @@ -4,7 +4,6 @@ package com.lithic.api.services.blocking -import com.lithic.api.core.JsonValue import com.lithic.api.core.RequestOptions import com.lithic.api.models.Event import com.lithic.api.models.EventListAttemptsPage @@ -35,6 +34,4 @@ interface EventService { params: EventListAttemptsParams, requestOptions: RequestOptions = RequestOptions.none() ): EventListAttemptsPage - - fun resend(eventToken: String, eventSubscriptionToken: String, body: JsonValue) } diff --git a/lithic-kotlin-core/src/main/kotlin/com/lithic/api/services/blocking/EventServiceImpl.kt b/lithic-kotlin-core/src/main/kotlin/com/lithic/api/services/blocking/EventServiceImpl.kt index d4136065..ce5709b7 100644 --- a/lithic-kotlin-core/src/main/kotlin/com/lithic/api/services/blocking/EventServiceImpl.kt +++ b/lithic-kotlin-core/src/main/kotlin/com/lithic/api/services/blocking/EventServiceImpl.kt @@ -3,7 +3,6 @@ package com.lithic.api.services.blocking import com.lithic.api.core.ClientOptions -import com.lithic.api.core.JsonValue import com.lithic.api.core.RequestOptions import com.lithic.api.core.http.HttpMethod import com.lithic.api.core.http.HttpRequest @@ -17,9 +16,7 @@ import com.lithic.api.models.EventListParams import com.lithic.api.models.EventRetrieveParams import com.lithic.api.services.blocking.events.SubscriptionService import com.lithic.api.services.blocking.events.SubscriptionServiceImpl -import com.lithic.api.services.emptyHandler import com.lithic.api.services.errorHandler -import com.lithic.api.services.json import com.lithic.api.services.jsonHandler import com.lithic.api.services.withErrorHandler @@ -113,22 +110,4 @@ constructor( .let { EventListAttemptsPage.of(this, params, it) } } } - - override fun resend(eventToken: String, eventSubscriptionToken: String, body: JsonValue) { - val request = - HttpRequest.builder() - .method(HttpMethod.POST) - .addPathSegments( - "events", - eventToken, - "event_subscriptions", - eventSubscriptionToken, - "resend" - ) - .body(json(clientOptions.jsonMapper, body)) - .build() - clientOptions.httpClient.execute(request).let { response -> - response.let { emptyHandler().handle(it) } - } - } } diff --git a/lithic-kotlin-core/src/main/kotlin/com/lithic/api/services/blocking/WebhookService.kt b/lithic-kotlin-core/src/main/kotlin/com/lithic/api/services/blocking/WebhookService.kt deleted file mode 100644 index fc9d0db1..00000000 --- a/lithic-kotlin-core/src/main/kotlin/com/lithic/api/services/blocking/WebhookService.kt +++ /dev/null @@ -1,15 +0,0 @@ -// File generated from our OpenAPI spec by Stainless. - -@file:Suppress("OVERLOADS_INTERFACE") // See https://youtrack.jetbrains.com/issue/KT-36102 - -package com.lithic.api.services.blocking - -import com.google.common.collect.ListMultimap -import com.lithic.api.core.JsonValue - -interface WebhookService { - - fun unwrap(payload: String, headers: ListMultimap, secret: String?): JsonValue - - fun verifySignature(payload: String, headers: ListMultimap, secret: String?) -} diff --git a/lithic-kotlin-core/src/main/kotlin/com/lithic/api/services/blocking/WebhookServiceImpl.kt b/lithic-kotlin-core/src/main/kotlin/com/lithic/api/services/blocking/WebhookServiceImpl.kt deleted file mode 100644 index 3f71c929..00000000 --- a/lithic-kotlin-core/src/main/kotlin/com/lithic/api/services/blocking/WebhookServiceImpl.kt +++ /dev/null @@ -1,101 +0,0 @@ -// File generated from our OpenAPI spec by Stainless. - -package com.lithic.api.services.blocking - -import com.fasterxml.jackson.core.JsonProcessingException -import com.google.common.collect.ListMultimap -import com.lithic.api.core.ClientOptions -import com.lithic.api.core.JsonValue -import com.lithic.api.core.getRequiredHeader -import com.lithic.api.core.http.HttpResponse.Handler -import com.lithic.api.errors.LithicError -import com.lithic.api.errors.LithicException -import com.lithic.api.services.errorHandler -import java.security.MessageDigest -import java.time.Duration -import java.time.Instant -import java.util.Base64 -import javax.crypto.Mac -import javax.crypto.spec.SecretKeySpec - -class WebhookServiceImpl -constructor( - private val clientOptions: ClientOptions, -) : WebhookService { - - private val errorHandler: Handler = errorHandler(clientOptions.jsonMapper) - - override fun unwrap( - payload: String, - headers: ListMultimap, - secret: String? - ): JsonValue { - verifySignature(payload, headers, secret) - return try { - clientOptions.jsonMapper.readValue(payload, JsonValue::class.java) - } catch (e: JsonProcessingException) { - throw LithicException("Invalid event payload", e) - } - } - - override fun verifySignature( - payload: String, - headers: ListMultimap, - secret: String? - ) { - val webhookSecret = - secret - ?: clientOptions.webhookSecret - ?: throw LithicException( - "The webhook secret must either be set using the env var, LITHIC_WEBHOOK_SECRET, on the client class, or passed to this method" - ) - - val whsecret = - try { - Base64.getDecoder().decode(webhookSecret.removePrefix("whsec_")) - } catch (e: RuntimeException) { - throw LithicException("Invalid webhook secret") - } - - val msgId = headers.getRequiredHeader("webhook-id") - val msgSignature = headers.getRequiredHeader("webhook-signature") - val msgTimestamp = headers.getRequiredHeader("webhook-timestamp") - - val timestamp = - try { - Instant.ofEpochSecond(msgTimestamp.toLong()) - } catch (e: RuntimeException) { - throw LithicException("Invalid signature headers", e) - } - val now = Instant.now(clientOptions.clock) - - if (timestamp.isBefore(now.minus(Duration.ofMinutes(5)))) { - throw LithicException("Webhook timestamp too old") - } - if (timestamp.isAfter(now.plus(Duration.ofMinutes(5)))) { - throw LithicException("Webhook timestamp too new") - } - - val mac = Mac.getInstance("HmacSHA256") - mac.init(SecretKeySpec(whsecret, "HmacSHA256")) - val expectedSignature = - mac.doFinal("$msgId.${timestamp.epochSecond}.$payload".toByteArray()) - - msgSignature.splitToSequence(" ").forEach { - val parts = it.split(",") - if (parts.size != 2) { - return@forEach - } - - if (parts[0] != "v1") { - return@forEach - } - - if (MessageDigest.isEqual(Base64.getDecoder().decode(parts[1]), expectedSignature)) { - return - } - } - - throw LithicException("None of the given webhook signatures match the expected signature") - } -} diff --git a/lithic-kotlin-core/src/test/kotlin/com/lithic/api/models/CardGetEmbedHtmlParamsTest.kt b/lithic-kotlin-core/src/test/kotlin/com/lithic/api/models/CardGetEmbedHtmlParamsTest.kt deleted file mode 100644 index d9971cd9..00000000 --- a/lithic-kotlin-core/src/test/kotlin/com/lithic/api/models/CardGetEmbedHtmlParamsTest.kt +++ /dev/null @@ -1,47 +0,0 @@ -// File generated from our OpenAPI spec by Stainless. - -package com.lithic.api.models - -import com.lithic.api.models.* -import java.time.OffsetDateTime -import org.assertj.core.api.Assertions.assertThat -import org.junit.jupiter.api.Test - -class CardGetEmbedHtmlParamsTest { - - @Test - fun createCardGetEmbedHtmlParams() { - CardGetEmbedHtmlParams.builder() - .token("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .css("string") - .expiration(OffsetDateTime.parse("2019-12-27T18:11:19.117Z")) - .targetOrigin("string") - .build() - } - - @Test - fun getBody() { - val params = - CardGetEmbedHtmlParams.builder() - .token("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .css("string") - .expiration(OffsetDateTime.parse("2019-12-27T18:11:19.117Z")) - .targetOrigin("string") - .build() - val body = params.getBody() - assertThat(body).isNotNull - assertThat(body.token()).isEqualTo("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - assertThat(body.css()).isEqualTo("string") - assertThat(body.expiration()).isEqualTo(OffsetDateTime.parse("2019-12-27T18:11:19.117Z")) - assertThat(body.targetOrigin()).isEqualTo("string") - } - - @Test - fun getBodyWithoutOptionalFields() { - val params = - CardGetEmbedHtmlParams.builder().token("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e").build() - val body = params.getBody() - assertThat(body).isNotNull - assertThat(body.token()).isEqualTo("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - } -} diff --git a/lithic-kotlin-core/src/test/kotlin/com/lithic/api/models/CardGetEmbedUrlParamsTest.kt b/lithic-kotlin-core/src/test/kotlin/com/lithic/api/models/CardGetEmbedUrlParamsTest.kt deleted file mode 100644 index fe70f790..00000000 --- a/lithic-kotlin-core/src/test/kotlin/com/lithic/api/models/CardGetEmbedUrlParamsTest.kt +++ /dev/null @@ -1,47 +0,0 @@ -// File generated from our OpenAPI spec by Stainless. - -package com.lithic.api.models - -import com.lithic.api.models.* -import java.time.OffsetDateTime -import org.assertj.core.api.Assertions.assertThat -import org.junit.jupiter.api.Test - -class CardGetEmbedUrlParamsTest { - - @Test - fun createCardGetEmbedUrlParams() { - CardGetEmbedUrlParams.builder() - .token("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .css("string") - .expiration(OffsetDateTime.parse("2019-12-27T18:11:19.117Z")) - .targetOrigin("string") - .build() - } - - @Test - fun getBody() { - val params = - CardGetEmbedUrlParams.builder() - .token("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .css("string") - .expiration(OffsetDateTime.parse("2019-12-27T18:11:19.117Z")) - .targetOrigin("string") - .build() - val body = params.getBody() - assertThat(body).isNotNull - assertThat(body.token()).isEqualTo("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - assertThat(body.css()).isEqualTo("string") - assertThat(body.expiration()).isEqualTo(OffsetDateTime.parse("2019-12-27T18:11:19.117Z")) - assertThat(body.targetOrigin()).isEqualTo("string") - } - - @Test - fun getBodyWithoutOptionalFields() { - val params = - CardGetEmbedUrlParams.builder().token("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e").build() - val body = params.getBody() - assertThat(body).isNotNull - assertThat(body.token()).isEqualTo("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - } -} diff --git a/lithic-kotlin-core/src/test/kotlin/com/lithic/api/services/blocking/CardServiceTest.kt b/lithic-kotlin-core/src/test/kotlin/com/lithic/api/services/blocking/CardServiceTest.kt index 5514cee2..ef598a2d 100644 --- a/lithic-kotlin-core/src/test/kotlin/com/lithic/api/services/blocking/CardServiceTest.kt +++ b/lithic-kotlin-core/src/test/kotlin/com/lithic/api/services/blocking/CardServiceTest.kt @@ -259,34 +259,4 @@ class CardServiceTest { println(card) card.validate() } - - @Test - fun callGetEmbedHtml() { - val client = - LithicOkHttpClient.builder() - .baseUrl(TestServerExtension.BASE_URL) - .apiKey("test-api-key") - .webhookSecret("string") - .build() - val cardService = client.cards() - val cardEmbedResponse = - cardService.getEmbedHtml(CardGetEmbedHtmlParams.builder().token("foo").build()) - println(cardEmbedResponse) - assertThat(cardEmbedResponse).contains("") - } - - @Test - fun callGetEmbedUrl() { - val client = - LithicOkHttpClient.builder() - .baseUrl(TestServerExtension.BASE_URL) - .apiKey("test-api-key") - .webhookSecret("string") - .build() - val cardService = client.cards() - val cardEmbedUrl = - cardService.getEmbedUrl(CardGetEmbedUrlParams.builder().token("foo").build()) - println(cardEmbedUrl) - assertThat(cardEmbedUrl).contains("hmac") - } } diff --git a/lithic-kotlin-core/src/test/kotlin/com/lithic/api/services/blocking/EventServiceTest.kt b/lithic-kotlin-core/src/test/kotlin/com/lithic/api/services/blocking/EventServiceTest.kt index d81cecf0..78dec67b 100644 --- a/lithic-kotlin-core/src/test/kotlin/com/lithic/api/services/blocking/EventServiceTest.kt +++ b/lithic-kotlin-core/src/test/kotlin/com/lithic/api/services/blocking/EventServiceTest.kt @@ -4,7 +4,6 @@ package com.lithic.api.services.blocking import com.lithic.api.TestServerExtension import com.lithic.api.client.okhttp.LithicOkHttpClient -import com.lithic.api.core.JsonString import com.lithic.api.models.* import com.lithic.api.models.EventListAttemptsParams import com.lithic.api.models.EventListParams @@ -56,16 +55,4 @@ class EventServiceTest { println(response) response.data().forEach { it.validate() } } - - @Test - fun callResend() { - val client = - LithicOkHttpClient.builder() - .baseUrl(TestServerExtension.BASE_URL) - .apiKey("test-api-key") - .webhookSecret("string") - .build() - val eventService = client.events() - eventService.resend("eventToken", "eventSubscriptionToken", JsonString.of("body")) - } } diff --git a/lithic-kotlin-core/src/test/kotlin/com/lithic/api/services/blocking/WebhookServiceTest.kt b/lithic-kotlin-core/src/test/kotlin/com/lithic/api/services/blocking/WebhookServiceTest.kt deleted file mode 100644 index bbf80d57..00000000 --- a/lithic-kotlin-core/src/test/kotlin/com/lithic/api/services/blocking/WebhookServiceTest.kt +++ /dev/null @@ -1,191 +0,0 @@ -// File generated from our OpenAPI spec by Stainless. - -package com.lithic.api.services.blocking - -import com.google.common.collect.ImmutableListMultimap -import com.lithic.api.TestServerExtension -import com.lithic.api.client.okhttp.LithicOkHttpClient -import com.lithic.api.errors.LithicException -import com.lithic.api.models.* -import java.time.Clock -import java.time.Instant -import java.time.ZoneOffset -import org.assertj.core.api.Assertions.* -import org.assertj.core.api.Assertions.assertThat -import org.junit.jupiter.api.Test -import org.junit.jupiter.api.extension.ExtendWith - -@ExtendWith(TestServerExtension::class) -class WebhookServiceTest { - - @Test - fun unwrap() { - val client = - LithicOkHttpClient.builder() - .apiKey("test-api-key") - .webhookSecret("whsec_zlFsbBZ8Xcodlpcu6NDTdSzZRLSdhkst") - .clock(Clock.fixed(Instant.ofEpochSecond(1676312382), ZoneOffset.UTC)) - .build() - - val payload = - "{\"card_token\":\"sit Lorem ipsum, accusantium repellendus possimus\",\"created_at\":\"elit. placeat libero architecto molestias, sit\",\"account_token\":\"elit.\",\"issuer_decision\":\"magnam, libero esse Lorem ipsum magnam, magnam,\",\"tokenization_attempt_id\":\"illum dolor repellendus libero esse accusantium\",\"wallet_decisioning_info\":{\"device_score\":\"placeat architecto\"},\"digital_wallet_token_metadata\":{\"status\":\"reprehenderit dolor\",\"token_requestor_id\":\"possimus\",\"payment_account_info\":{\"account_holder_data\":{\"phone_number\":\"libero\",\"email_address\":\"nobis molestias, veniam culpa! quas elit. quas libero esse architecto placeat\"},\"pan_unique_reference\":\"adipisicing odit magnam, odit\"}}}" - val headers = - ImmutableListMultimap.of( - "webhook-id", - "msg_2Lh9KRb0pzN4LePd3XiA4v12Axj", - "webhook-timestamp", - "1676312382", - "webhook-signature", - "v1,Dwa0AHInLL3XFo2sxcHamOQDrJNi7F654S3L6skMAOI=" - ) - - val event = client.webhooks().unwrap(payload, headers, null) - - assertThat(event).isNotNull() - } - - @Test - fun verifySignature() { - val client = - LithicOkHttpClient.builder() - .apiKey("test-api-key") - .webhookSecret("whsec_zlFsbBZ8Xcodlpcu6NDTdSzZRLSdhkst") - .clock(Clock.fixed(Instant.ofEpochSecond(1676312382), ZoneOffset.UTC)) - .build() - - val payload = - "{\"card_token\":\"sit Lorem ipsum, accusantium repellendus possimus\",\"created_at\":\"elit. placeat libero architecto molestias, sit\",\"account_token\":\"elit.\",\"issuer_decision\":\"magnam, libero esse Lorem ipsum magnam, magnam,\",\"tokenization_attempt_id\":\"illum dolor repellendus libero esse accusantium\",\"wallet_decisioning_info\":{\"device_score\":\"placeat architecto\"},\"digital_wallet_token_metadata\":{\"status\":\"reprehenderit dolor\",\"token_requestor_id\":\"possimus\",\"payment_account_info\":{\"account_holder_data\":{\"phone_number\":\"libero\",\"email_address\":\"nobis molestias, veniam culpa! quas elit. quas libero esse architecto placeat\"},\"pan_unique_reference\":\"adipisicing odit magnam, odit\"}}}" - val webhookId = "msg_2Lh9KRb0pzN4LePd3XiA4v12Axj" - val webhookTimestamp = "1676312382" - val webhookSignature = "Dwa0AHInLL3XFo2sxcHamOQDrJNi7F654S3L6skMAOI=" - val headers = - ImmutableListMultimap.of( - "webhook-id", - webhookId, - "webhook-timestamp", - webhookTimestamp, - "webhook-signature", - "v1,$webhookSignature" - ) - - assertThatThrownBy { - client - .webhooks() - .verifySignature( - payload, - ImmutableListMultimap.of( - "webhook-id", - webhookId, - "webhook-timestamp", - "1676312022", - "webhook-signature", - "v1,$webhookSignature" - ), - null - ) - } - .isInstanceOf(LithicException::class.java) - .hasMessage("Webhook timestamp too old") - - assertThatThrownBy { - client - .webhooks() - .verifySignature( - payload, - ImmutableListMultimap.of( - "webhook-id", - webhookId, - "webhook-timestamp", - "1676312742", - "webhook-signature", - "v1,$webhookSignature" - ), - null - ) - } - .isInstanceOf(LithicException::class.java) - .hasMessage("Webhook timestamp too new") - - assertThatThrownBy { client.webhooks().verifySignature(payload, headers, "invalid-secret") } - .isInstanceOf(LithicException::class.java) - .hasMessage("Invalid webhook secret") - - assertThatThrownBy { client.webhooks().verifySignature(payload, headers, "Zm9v") } - .isInstanceOf(LithicException::class.java) - .hasMessage("None of the given webhook signatures match the expected signature") - - assertThatCode { - client - .webhooks() - .verifySignature( - payload, - ImmutableListMultimap.of( - "webhook-id", - webhookId, - "webhook-timestamp", - webhookTimestamp, - "webhook-signature", - "v1,$webhookSignature v1,Zm9v", - ), - null - ) - } - .doesNotThrowAnyException() - - assertThatThrownBy { - client - .webhooks() - .verifySignature( - payload, - ImmutableListMultimap.of( - "webhook-id", - webhookId, - "webhook-timestamp", - webhookTimestamp, - "webhook-signature", - "v2,$webhookSignature", - ), - null - ) - } - .isInstanceOf(LithicException::class.java) - .hasMessage("None of the given webhook signatures match the expected signature") - - assertThatCode { - client - .webhooks() - .verifySignature( - payload, - ImmutableListMultimap.of( - "webhook-id", - webhookId, - "webhook-timestamp", - webhookTimestamp, - "webhook-signature", - "v1,$webhookSignature v2,$webhookSignature", - ), - null - ) - } - .doesNotThrowAnyException() - - assertThatThrownBy { - client - .webhooks() - .verifySignature( - payload, - ImmutableListMultimap.of( - "webhook-id", - webhookId, - "webhook-timestamp", - webhookTimestamp, - "webhook-signature", - webhookSignature, - ), - null - ) - } - .isInstanceOf(LithicException::class.java) - .hasMessage("None of the given webhook signatures match the expected signature") - } -}