Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion stytch/src/main/kotlin/com/stytch/java/common/Version.kt
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
package com.stytch.java.common

internal const val VERSION = "9.1.0"
internal const val VERSION = "9.2.0"
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -23,6 +25,8 @@ public interface Fraud {
public val rules: Rules

public val verdictReasons: VerdictReasons

public val email: Email
}

internal class FraudImpl(
Expand All @@ -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)
}
Original file line number Diff line number Diff line change
@@ -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<RiskResponse>

/**
* 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<RiskResponse>) -> 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<StytchResult<RiskResponse>>
}

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<RiskResponse> =
withContext(Dispatchers.IO) {
var headers = emptyMap<String, String>()

val asJson = moshi.adapter(RiskRequest::class.java).toJson(data)
httpClient.post("/v1/email/risk", asJson, headers)
}

override fun risk(
data: RiskRequest,
callback: (StytchResult<RiskResponse>) -> Unit,
) {
coroutineScope.launch {
callback(risk(data))
}
}

override fun riskCompletable(data: RiskRequest): CompletableFuture<StytchResult<RiskResponse>> =
coroutineScope
.async {
risk(data)
}.asCompletableFuture()
}
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand Down
Original file line number Diff line number Diff line change
@@ -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,
)
2 changes: 1 addition & 1 deletion version.gradle.kts
Original file line number Diff line number Diff line change
@@ -1 +1 @@
version = "9.1.0"
version = "9.2.0"
Loading