diff --git a/stytch/src/main/kotlin/com/stytch/java/common/Version.kt b/stytch/src/main/kotlin/com/stytch/java/common/Version.kt index 228bef9..d3e96de 100644 --- a/stytch/src/main/kotlin/com/stytch/java/common/Version.kt +++ b/stytch/src/main/kotlin/com/stytch/java/common/Version.kt @@ -1,3 +1,3 @@ package com.stytch.java.common -internal const val VERSION = "9.1.0" +internal const val VERSION = "9.2.0" diff --git a/stytch/src/main/kotlin/com/stytch/java/consumer/api/fraud/Fraud.kt b/stytch/src/main/kotlin/com/stytch/java/consumer/api/fraud/Fraud.kt index 5a27caf..0f2aaa3 100644 --- a/stytch/src/main/kotlin/com/stytch/java/consumer/api/fraud/Fraud.kt +++ b/stytch/src/main/kotlin/com/stytch/java/consumer/api/fraud/Fraud.kt @@ -8,6 +8,8 @@ package com.stytch.java.consumer.api.fraud import com.squareup.moshi.Moshi import com.stytch.java.common.InstantAdapter +import com.stytch.java.consumer.api.fraudemail.Email +import com.stytch.java.consumer.api.fraudemail.EmailImpl import com.stytch.java.consumer.api.fraudfingerprint.Fingerprint import com.stytch.java.consumer.api.fraudfingerprint.FingerprintImpl import com.stytch.java.consumer.api.fraudrules.Rules @@ -23,6 +25,8 @@ public interface Fraud { public val rules: Rules public val verdictReasons: VerdictReasons + + public val email: Email } internal class FraudImpl( @@ -34,4 +38,5 @@ internal class FraudImpl( override val fingerprint: Fingerprint = FingerprintImpl(httpClient, coroutineScope) override val rules: Rules = RulesImpl(httpClient, coroutineScope) override val verdictReasons: VerdictReasons = VerdictReasonsImpl(httpClient, coroutineScope) + override val email: Email = EmailImpl(httpClient, coroutineScope) } diff --git a/stytch/src/main/kotlin/com/stytch/java/consumer/api/fraudemail/FraudEmail.kt b/stytch/src/main/kotlin/com/stytch/java/consumer/api/fraudemail/FraudEmail.kt new file mode 100644 index 0000000..077408e --- /dev/null +++ b/stytch/src/main/kotlin/com/stytch/java/consumer/api/fraudemail/FraudEmail.kt @@ -0,0 +1,89 @@ +package com.stytch.java.consumer.api.fraudemail + +// !!! +// WARNING: This file is autogenerated +// Only modify code within MANUAL() sections +// or your changes may be overwritten later! +// !!! + +import com.squareup.moshi.Moshi +import com.stytch.java.common.InstantAdapter +import com.stytch.java.common.StytchResult +import com.stytch.java.consumer.models.fraudemail.RiskRequest +import com.stytch.java.consumer.models.fraudemail.RiskResponse +import com.stytch.java.http.HttpClient +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.async +import kotlinx.coroutines.future.asCompletableFuture +import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext +import java.util.concurrent.CompletableFuture + +public interface Email { + /** + * Get risk information for a specific email address. + * The response will contain a recommended action (`ALLOW`, `BLOCK`, or `CHALLENGE`) and a more granular `risk_score`. + * You can also check the `address_information` and `domain_information` fields for more information about the email + * address and email domain. + * + * This feature is in beta. Reach out to us [here](mailto:fraud-team@stytch.com?subject=Email_Intelligence_Early_Access) + * if you'd like to request early access. + */ + public suspend fun risk(data: RiskRequest): StytchResult + + /** + * Get risk information for a specific email address. + * The response will contain a recommended action (`ALLOW`, `BLOCK`, or `CHALLENGE`) and a more granular `risk_score`. + * You can also check the `address_information` and `domain_information` fields for more information about the email + * address and email domain. + * + * This feature is in beta. Reach out to us [here](mailto:fraud-team@stytch.com?subject=Email_Intelligence_Early_Access) + * if you'd like to request early access. + */ + public fun risk( + data: RiskRequest, + callback: (StytchResult) -> Unit, + ) + + /** + * Get risk information for a specific email address. + * The response will contain a recommended action (`ALLOW`, `BLOCK`, or `CHALLENGE`) and a more granular `risk_score`. + * You can also check the `address_information` and `domain_information` fields for more information about the email + * address and email domain. + * + * This feature is in beta. Reach out to us [here](mailto:fraud-team@stytch.com?subject=Email_Intelligence_Early_Access) + * if you'd like to request early access. + */ + public fun riskCompletable(data: RiskRequest): CompletableFuture> +} + +internal class EmailImpl( + private val httpClient: HttpClient, + private val coroutineScope: CoroutineScope, +) : Email { + private val moshi = Moshi.Builder().add(InstantAdapter()).build() + + override suspend fun risk(data: RiskRequest): StytchResult = + withContext(Dispatchers.IO) { + var headers = emptyMap() + + val asJson = moshi.adapter(RiskRequest::class.java).toJson(data) + httpClient.post("/v1/email/risk", asJson, headers) + } + + override fun risk( + data: RiskRequest, + callback: (StytchResult) -> Unit, + ) { + coroutineScope.launch { + callback(risk(data)) + } + } + + override fun riskCompletable(data: RiskRequest): CompletableFuture> = + coroutineScope + .async { + risk(data) + }.asCompletableFuture() +} diff --git a/stytch/src/main/kotlin/com/stytch/java/consumer/models/fraud/Fraud.kt b/stytch/src/main/kotlin/com/stytch/java/consumer/models/fraud/Fraud.kt index 31def10..96ba919 100644 --- a/stytch/src/main/kotlin/com/stytch/java/consumer/models/fraud/Fraud.kt +++ b/stytch/src/main/kotlin/com/stytch/java/consumer/models/fraud/Fraud.kt @@ -112,6 +112,38 @@ public data class ASNProperties val network: String, ) +@JsonClass(generateAdapter = true) +public data class AddressInformation + @JvmOverloads + constructor( + /** + * Whether email sent to this address is known to have bounced previously. + */ + @Json(name = "has_known_bounces") + val hasKnownBounces: Boolean, + /** + * Whether this email address is valid. + */ + @Json(name = "has_valid_syntax") + val hasValidSyntax: Boolean, + /** + * Whether the local part of the email appears to be a role or group, rather than an individual end user. + */ + @Json(name = "is_suspected_role_address") + val isSuspectedRoleAddress: Boolean, + /** + * The normalized email address after removing '.' characters and any characters after a '+'. + */ + @Json(name = "normalized_email") + val normalizedEmail: String, + /** + * The number of '.' and '+' characters in the email address. A higher tumbling count indicates a higher potential for + * fraud. + */ + @Json(name = "tumbling_character_count") + val tumblingCharacterCount: Int, + ) + @JsonClass(generateAdapter = true) public data class BrowserProperties @JvmOverloads @@ -123,6 +155,22 @@ public data class BrowserProperties val userAgent: String, ) +@JsonClass(generateAdapter = true) +public data class DomainInformation + @JvmOverloads + constructor( + /** + * Whether the email has appropriate DNS records to deliver a message. + */ + @Json(name = "has_mx_or_a_record") + val hasMXOrARecord: Boolean, + /** + * Whether the email domain is known to be disposable. + */ + @Json(name = "is_disposable_domain") + val isDisposableDomain: Boolean, + ) + @JsonClass(generateAdapter = true) public data class Fingerprints @JvmOverloads diff --git a/stytch/src/main/kotlin/com/stytch/java/consumer/models/fraudemail/FraudEmail.kt b/stytch/src/main/kotlin/com/stytch/java/consumer/models/fraudemail/FraudEmail.kt new file mode 100644 index 0000000..ae8fdfb --- /dev/null +++ b/stytch/src/main/kotlin/com/stytch/java/consumer/models/fraudemail/FraudEmail.kt @@ -0,0 +1,84 @@ +package com.stytch.java.consumer.models.fraudemail + +// !!! +// WARNING: This file is autogenerated +// Only modify code within MANUAL() sections +// or your changes may be overwritten later! +// !!! + +import com.squareup.moshi.Json +import com.squareup.moshi.JsonClass +import com.stytch.java.consumer.models.fraud.AddressInformation +import com.stytch.java.consumer.models.fraud.DomainInformation + +@JsonClass(generateAdapter = false) +public enum class RiskResponseAction { + @Json(name = "ALLOW") + ALLOW, + + @Json(name = "CHALLENGE") + CHALLENGE, + + @Json(name = "BLOCK") + BLOCK, +} + +/** +* Request type for `Email.risk`. +*/ +@JsonClass(generateAdapter = true) +public data class RiskRequest + @JvmOverloads + constructor( + /** + * The email address to check. + */ + @Json(name = "email_address") + val emailAddress: String, + ) + +/** +* Response type for `Email.risk`. +*/ +@JsonClass(generateAdapter = true) +public data class RiskResponse + @JvmOverloads + constructor( + /** + * Globally unique UUID that is returned with every API call. This value is important to log for debugging purposes; we + * may ask for this value to help identify a specific API call when helping you debug an issue. + */ + @Json(name = "request_id") + val requestId: String, + /** + * Information about the email address. + */ + @Json(name = "address_information") + val addressInformation: AddressInformation, + /** + * Information about the email domain. + */ + @Json(name = "domain_information") + val domainInformation: DomainInformation, + /** + * The suggested action based on the attributes of the email address. The available actions are: + * * `ALLOW` - This email is most likely safe to send to and not fraudulent. + * * `BLOCK` - This email is invalid or exhibits signs of fraud. We recommend blocking the end user. + * * `CHALLENGE` - This email has some potentially fraudulent attributes. We recommend increased friction such as 2FA or + * other forms of extended user verification before allowing the privileged action to proceed. + * + */ + @Json(name = "action") + val action: RiskResponseAction, + /** + * A score from 0 to 100 indicating how risky the email is. 100 is the most risky. + */ + @Json(name = "risk_score") + val riskScore: Int, + /** + * The HTTP status code of the response. Stytch follows standard HTTP response status code patterns, e.g. 2XX values + * equate to success, 3XX values are redirects, 4XX are client errors, and 5XX are server errors. + */ + @Json(name = "status_code") + val statusCode: Int, + ) diff --git a/version.gradle.kts b/version.gradle.kts index a046088..3e1d71c 100644 --- a/version.gradle.kts +++ b/version.gradle.kts @@ -1 +1 @@ -version = "9.1.0" +version = "9.2.0"