diff --git a/.changeset/forty-seas-prove.md b/.changeset/forty-seas-prove.md new file mode 100644 index 0000000..4f10093 --- /dev/null +++ b/.changeset/forty-seas-prove.md @@ -0,0 +1,5 @@ +--- +'fingerprint-pro-server-api-java-sdk': minor +--- + +Add `relay` detection method to the VPN Detection Smart Signal diff --git a/.changeset/orange-poets-drive.md b/.changeset/orange-poets-drive.md new file mode 100644 index 0000000..c297c6f --- /dev/null +++ b/.changeset/orange-poets-drive.md @@ -0,0 +1,5 @@ +--- +'fingerprint-pro-server-api-java-sdk': minor +--- + +**events**: Add a `suspect` field to the `identification` product schema \ No newline at end of file diff --git a/.schema-version b/.schema-version index 852700e..cf2dc0b 100644 --- a/.schema-version +++ b/.schema-version @@ -1 +1 @@ -v2.1.0 \ No newline at end of file +v2.2.0 \ No newline at end of file diff --git a/docs/FactoryReset.md b/docs/FactoryReset.md index 96b0512..d684683 100644 --- a/docs/FactoryReset.md +++ b/docs/FactoryReset.md @@ -8,7 +8,7 @@ | Name | Type | Description | Notes | |------------ | ------------- | ------------- | -------------| |**time** | **OffsetDateTime** | Indicates the time (in UTC) of the most recent factory reset that happened on the **mobile device**. When a factory reset cannot be detected on the mobile device or when the request is initiated from a browser, this field will correspond to the *epoch* time (i.e 1 Jan 1970 UTC). See [Factory Reset Detection](https://dev.fingerprint.com/docs/smart-signals-overview#factory-reset-detection) to learn more about this Smart Signal. | | -|**timestamp** | **Long** | This field is just another representation of the value in the `time` field. The time of the most recent factory reset that happened on the **mobile device** is expressed as Unix epoch time. | | +|**timestamp** | **Long** | This field is just another representation of the value in the `time` field. The time of the most recent factory reset that happened on the **mobile device** is expressed as Unix epoch time. | | diff --git a/docs/Identification.md b/docs/Identification.md index 3181712..5180053 100644 --- a/docs/Identification.md +++ b/docs/Identification.md @@ -14,6 +14,7 @@ |**ip** | **String** | IP address of the requesting browser or bot. | | |**ipLocation** | [**DeprecatedGeolocation**](DeprecatedGeolocation.md) | | [optional] | |**linkedId** | **String** | A customer-provided id that was sent with the request. | [optional] | +|**suspect** | **Boolean** | Field is `true` if you have previously set the `suspect` flag for this event using the [Server API Update event endpoint](https://dev.fingerprint.com/reference/updateevent). | [optional] | |**timestamp** | **Long** | Timestamp of the event with millisecond precision in Unix time. | | |**time** | **OffsetDateTime** | Time expressed according to ISO 8601 in UTC format, when the request from the JS agent was made. We recommend to treat requests that are older than 2 minutes as malicious. Otherwise, request replay attacks are possible. | | |**url** | **String** | Page URL from which the request was sent. | | diff --git a/docs/VPNMethods.md b/docs/VPNMethods.md index 0c6debb..b477be4 100644 --- a/docs/VPNMethods.md +++ b/docs/VPNMethods.md @@ -11,6 +11,7 @@ |**publicVPN** | **Boolean** | Request IP address is owned and used by a public VPN service provider. | | |**auxiliaryMobile** | **Boolean** | This method applies to mobile devices only. Indicates the result of additional methods used to detect a VPN in mobile devices. | | |**osMismatch** | **Boolean** | The browser runs on a different operating system than the operating system inferred from the request network signature. | | +|**relay** | **Boolean** | Request IP address belongs to a relay service provider, indicating the use of relay services like [Apple Private relay](https://support.apple.com/en-us/102602) or [Cloudflare Warp](https://developers.cloudflare.com/warp-client/). * Like VPNs, relay services anonymize the visitor's true IP address. * Unlike traditional VPNs, relay services don't let visitors spoof their location by choosing an exit node in a different country. This field allows you to differentiate VPN users and relay service users in your fraud prevention logic. | | diff --git a/docs/WebhookFactoryReset.md b/docs/WebhookFactoryReset.md index 415d60c..df083a9 100644 --- a/docs/WebhookFactoryReset.md +++ b/docs/WebhookFactoryReset.md @@ -8,7 +8,7 @@ | Name | Type | Description | Notes | |------------ | ------------- | ------------- | -------------| |**time** | **OffsetDateTime** | Indicates the time (in UTC) of the most recent factory reset that happened on the **mobile device**. When a factory reset cannot be detected on the mobile device or when the request is initiated from a browser, this field will correspond to the *epoch* time (i.e 1 Jan 1970 UTC). See [Factory Reset Detection](https://dev.fingerprint.com/docs/smart-signals-overview#factory-reset-detection) to learn more about this Smart Signal. | [optional] | -|**timestamp** | **Long** | This field is just another representation of the value in the `time` field. The time of the most recent factory reset that happened on the **mobile device** is expressed as Unix epoch time. | [optional] | +|**timestamp** | **Long** | This field is just another representation of the value in the `time` field. The time of the most recent factory reset that happened on the **mobile device** is expressed as Unix epoch time. | [optional] | diff --git a/res/fingerprint-server-api.yaml b/res/fingerprint-server-api.yaml index fc8d487..b5eaa9d 100644 --- a/res/fingerprint-server-api.yaml +++ b/res/fingerprint-server-api.yaml @@ -527,6 +527,7 @@ paths: publicVPN: false auxiliaryMobile: false osMismatch: false + relay: false proxy: result: false tampering: @@ -848,6 +849,12 @@ components: linkedId: type: string description: A customer-provided id that was sent with the request. + suspect: + description: >- + Field is `true` if you have previously set the `suspect` flag for + this event using the [Server API Update event + endpoint](https://dev.fingerprint.com/reference/updateevent). + type: boolean timestamp: description: Timestamp of the event with millisecond precision in Unix time. type: integer @@ -1218,6 +1225,7 @@ components: - publicVPN - auxiliaryMobile - osMismatch + - relay properties: timezoneMismatch: type: boolean @@ -1239,6 +1247,23 @@ components: description: >- The browser runs on a different operating system than the operating system inferred from the request network signature. + relay: + type: boolean + description: > + Request IP address belongs to a relay service provider, indicating + the use of relay services like [Apple Private + relay](https://support.apple.com/en-us/102602) or [Cloudflare + Warp](https://developers.cloudflare.com/warp-client/). + + + * Like VPNs, relay services anonymize the visitor's true IP address. + + * Unlike traditional VPNs, relay services don't let visitors spoof + their location by choosing an exit node in a different country. + + + This field allows you to differentiate VPN users and relay service + users in your fraud prevention logic. VPN: type: object additionalProperties: false @@ -1400,7 +1425,7 @@ components: field. The time of the most recent factory reset that happened on the - **mobile device** is expressed as Unix epoch time. + **mobile device** is expressed as Unix epoch time. ProductFactoryReset: type: object additionalProperties: false @@ -2022,7 +2047,7 @@ components: field. The time of the most recent factory reset that happened on the - **mobile device** is expressed as Unix epoch time. + **mobile device** is expressed as Unix epoch time. WebhookJailbroken: type: object additionalProperties: false diff --git a/sdk/src/main/java/com/fingerprint/model/FactoryReset.java b/sdk/src/main/java/com/fingerprint/model/FactoryReset.java index 71e1156..8fcf3b4 100644 --- a/sdk/src/main/java/com/fingerprint/model/FactoryReset.java +++ b/sdk/src/main/java/com/fingerprint/model/FactoryReset.java @@ -64,11 +64,11 @@ public FactoryReset timestamp(Long timestamp) { } /** - * This field is just another representation of the value in the `time` field. The time of the most recent factory reset that happened on the **mobile device** is expressed as Unix epoch time. + * This field is just another representation of the value in the `time` field. The time of the most recent factory reset that happened on the **mobile device** is expressed as Unix epoch time. * @return timestamp **/ @jakarta.annotation.Nonnull - @Schema(required = true, description = "This field is just another representation of the value in the `time` field. The time of the most recent factory reset that happened on the **mobile device** is expressed as Unix epoch time. ") + @Schema(required = true, description = "This field is just another representation of the value in the `time` field. The time of the most recent factory reset that happened on the **mobile device** is expressed as Unix epoch time. ") @JsonProperty(JSON_PROPERTY_TIMESTAMP) @JsonInclude(value = JsonInclude.Include.ALWAYS) diff --git a/sdk/src/main/java/com/fingerprint/model/Identification.java b/sdk/src/main/java/com/fingerprint/model/Identification.java index d048fac..a228a1c 100644 --- a/sdk/src/main/java/com/fingerprint/model/Identification.java +++ b/sdk/src/main/java/com/fingerprint/model/Identification.java @@ -32,6 +32,7 @@ Identification.JSON_PROPERTY_IP, Identification.JSON_PROPERTY_IP_LOCATION, Identification.JSON_PROPERTY_LINKED_ID, + Identification.JSON_PROPERTY_SUSPECT, Identification.JSON_PROPERTY_TIMESTAMP, Identification.JSON_PROPERTY_TIME, Identification.JSON_PROPERTY_URL, @@ -65,6 +66,9 @@ public class Identification { public static final String JSON_PROPERTY_LINKED_ID = "linkedId"; private String linkedId; + public static final String JSON_PROPERTY_SUSPECT = "suspect"; + private Boolean suspect; + public static final String JSON_PROPERTY_TIMESTAMP = "timestamp"; private Long timestamp; @@ -279,6 +283,32 @@ public void setLinkedId(String linkedId) { } + public Identification suspect(Boolean suspect) { + this.suspect = suspect; + return this; + } + + /** + * Field is `true` if you have previously set the `suspect` flag for this event using the [Server API Update event endpoint](https://dev.fingerprint.com/reference/updateevent). + * @return suspect + **/ + @jakarta.annotation.Nullable + @Schema(description = "Field is `true` if you have previously set the `suspect` flag for this event using the [Server API Update event endpoint](https://dev.fingerprint.com/reference/updateevent).") + @JsonProperty(JSON_PROPERTY_SUSPECT) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + + public Boolean getSuspect() { + return suspect; + } + + + @JsonProperty(JSON_PROPERTY_SUSPECT) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setSuspect(Boolean suspect) { + this.suspect = suspect; + } + + public Identification timestamp(Long timestamp) { this.timestamp = timestamp; return this; @@ -545,6 +575,7 @@ public boolean equals(Object o) { Objects.equals(this.ip, identification.ip) && Objects.equals(this.ipLocation, identification.ipLocation) && Objects.equals(this.linkedId, identification.linkedId) && + Objects.equals(this.suspect, identification.suspect) && Objects.equals(this.timestamp, identification.timestamp) && Objects.equals(this.time, identification.time) && Objects.equals(this.url, identification.url) && @@ -558,7 +589,7 @@ public boolean equals(Object o) { @Override public int hashCode() { - return Objects.hash(visitorId, requestId, browserDetails, incognito, ip, ipLocation, linkedId, timestamp, time, url, tag, confidence, visitorFound, firstSeenAt, lastSeenAt, components); + return Objects.hash(visitorId, requestId, browserDetails, incognito, ip, ipLocation, linkedId, suspect, timestamp, time, url, tag, confidence, visitorFound, firstSeenAt, lastSeenAt, components); } @Override @@ -572,6 +603,7 @@ public String toString() { sb.append(" ip: ").append(toIndentedString(ip)).append("\n"); sb.append(" ipLocation: ").append(toIndentedString(ipLocation)).append("\n"); sb.append(" linkedId: ").append(toIndentedString(linkedId)).append("\n"); + sb.append(" suspect: ").append(toIndentedString(suspect)).append("\n"); sb.append(" timestamp: ").append(toIndentedString(timestamp)).append("\n"); sb.append(" time: ").append(toIndentedString(time)).append("\n"); sb.append(" url: ").append(toIndentedString(url)).append("\n"); diff --git a/sdk/src/main/java/com/fingerprint/model/VPNMethods.java b/sdk/src/main/java/com/fingerprint/model/VPNMethods.java index abcdef8..8dd3d74 100644 --- a/sdk/src/main/java/com/fingerprint/model/VPNMethods.java +++ b/sdk/src/main/java/com/fingerprint/model/VPNMethods.java @@ -20,7 +20,8 @@ VPNMethods.JSON_PROPERTY_TIMEZONE_MISMATCH, VPNMethods.JSON_PROPERTY_PUBLIC_V_P_N, VPNMethods.JSON_PROPERTY_AUXILIARY_MOBILE, - VPNMethods.JSON_PROPERTY_OS_MISMATCH + VPNMethods.JSON_PROPERTY_OS_MISMATCH, + VPNMethods.JSON_PROPERTY_RELAY }) @jakarta.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", comments = "Generator version: 7.7.0") public class VPNMethods { @@ -36,6 +37,9 @@ public class VPNMethods { public static final String JSON_PROPERTY_OS_MISMATCH = "osMismatch"; private Boolean osMismatch; + public static final String JSON_PROPERTY_RELAY = "relay"; + private Boolean relay; + public VPNMethods() { } @@ -143,6 +147,32 @@ public void setOsMismatch(Boolean osMismatch) { } + public VPNMethods relay(Boolean relay) { + this.relay = relay; + return this; + } + + /** + * Request IP address belongs to a relay service provider, indicating the use of relay services like [Apple Private relay](https://support.apple.com/en-us/102602) or [Cloudflare Warp](https://developers.cloudflare.com/warp-client/). * Like VPNs, relay services anonymize the visitor's true IP address. * Unlike traditional VPNs, relay services don't let visitors spoof their location by choosing an exit node in a different country. This field allows you to differentiate VPN users and relay service users in your fraud prevention logic. + * @return relay + **/ + @jakarta.annotation.Nonnull + @Schema(required = true, description = "Request IP address belongs to a relay service provider, indicating the use of relay services like [Apple Private relay](https://support.apple.com/en-us/102602) or [Cloudflare Warp](https://developers.cloudflare.com/warp-client/). * Like VPNs, relay services anonymize the visitor's true IP address. * Unlike traditional VPNs, relay services don't let visitors spoof their location by choosing an exit node in a different country. This field allows you to differentiate VPN users and relay service users in your fraud prevention logic. ") + @JsonProperty(JSON_PROPERTY_RELAY) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + + public Boolean getRelay() { + return relay; + } + + + @JsonProperty(JSON_PROPERTY_RELAY) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setRelay(Boolean relay) { + this.relay = relay; + } + + /** * Return true if this VPNMethods object is equal to o. */ @@ -158,12 +188,13 @@ public boolean equals(Object o) { return Objects.equals(this.timezoneMismatch, vpNMethods.timezoneMismatch) && Objects.equals(this.publicVPN, vpNMethods.publicVPN) && Objects.equals(this.auxiliaryMobile, vpNMethods.auxiliaryMobile) && - Objects.equals(this.osMismatch, vpNMethods.osMismatch); + Objects.equals(this.osMismatch, vpNMethods.osMismatch) && + Objects.equals(this.relay, vpNMethods.relay); } @Override public int hashCode() { - return Objects.hash(timezoneMismatch, publicVPN, auxiliaryMobile, osMismatch); + return Objects.hash(timezoneMismatch, publicVPN, auxiliaryMobile, osMismatch, relay); } @Override @@ -174,6 +205,7 @@ public String toString() { sb.append(" publicVPN: ").append(toIndentedString(publicVPN)).append("\n"); sb.append(" auxiliaryMobile: ").append(toIndentedString(auxiliaryMobile)).append("\n"); sb.append(" osMismatch: ").append(toIndentedString(osMismatch)).append("\n"); + sb.append(" relay: ").append(toIndentedString(relay)).append("\n"); sb.append("}"); return sb.toString(); } diff --git a/sdk/src/main/java/com/fingerprint/model/WebhookFactoryReset.java b/sdk/src/main/java/com/fingerprint/model/WebhookFactoryReset.java index f8ecca3..6b83180 100644 --- a/sdk/src/main/java/com/fingerprint/model/WebhookFactoryReset.java +++ b/sdk/src/main/java/com/fingerprint/model/WebhookFactoryReset.java @@ -64,11 +64,11 @@ public WebhookFactoryReset timestamp(Long timestamp) { } /** - * This field is just another representation of the value in the `time` field. The time of the most recent factory reset that happened on the **mobile device** is expressed as Unix epoch time. + * This field is just another representation of the value in the `time` field. The time of the most recent factory reset that happened on the **mobile device** is expressed as Unix epoch time. * @return timestamp **/ @jakarta.annotation.Nullable - @Schema(description = "This field is just another representation of the value in the `time` field. The time of the most recent factory reset that happened on the **mobile device** is expressed as Unix epoch time. ") + @Schema(description = "This field is just another representation of the value in the `time` field. The time of the most recent factory reset that happened on the **mobile device** is expressed as Unix epoch time. ") @JsonProperty(JSON_PROPERTY_TIMESTAMP) @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) diff --git a/sdk/src/test/resources/mocks/errors/400_bot_type_invalid.json b/sdk/src/test/resources/mocks/errors/400_bot_type_invalid.json new file mode 100644 index 0000000..8dd6526 --- /dev/null +++ b/sdk/src/test/resources/mocks/errors/400_bot_type_invalid.json @@ -0,0 +1,6 @@ +{ + "error": { + "code": "RequestCannotBeParsed", + "message": "invalid bot type" + } +} diff --git a/sdk/src/test/resources/mocks/errors/400_end_time_invalid.json b/sdk/src/test/resources/mocks/errors/400_end_time_invalid.json new file mode 100644 index 0000000..8865409 --- /dev/null +++ b/sdk/src/test/resources/mocks/errors/400_end_time_invalid.json @@ -0,0 +1,6 @@ +{ + "error": { + "code": "RequestCannotBeParsed", + "message": "invalid end time" + } +} \ No newline at end of file diff --git a/sdk/src/test/resources/mocks/errors/400_ip_address_invalid.json b/sdk/src/test/resources/mocks/errors/400_ip_address_invalid.json new file mode 100644 index 0000000..5969bab --- /dev/null +++ b/sdk/src/test/resources/mocks/errors/400_ip_address_invalid.json @@ -0,0 +1,6 @@ +{ + "error": { + "code": "RequestCannotBeParsed", + "message": "invalid ip address" + } +} \ No newline at end of file diff --git a/sdk/src/test/resources/mocks/errors/400_limit_invalid.json b/sdk/src/test/resources/mocks/errors/400_limit_invalid.json new file mode 100644 index 0000000..46297eb --- /dev/null +++ b/sdk/src/test/resources/mocks/errors/400_limit_invalid.json @@ -0,0 +1,6 @@ +{ + "error": { + "code": "RequestCannotBeParsed", + "message": "invalid limit" + } +} diff --git a/sdk/src/test/resources/mocks/errors/400_linked_id_invalid.json b/sdk/src/test/resources/mocks/errors/400_linked_id_invalid.json new file mode 100644 index 0000000..72de54e --- /dev/null +++ b/sdk/src/test/resources/mocks/errors/400_linked_id_invalid.json @@ -0,0 +1,6 @@ +{ + "error": { + "code": "RequestCannotBeParsed", + "message": "linked_id can't be greater than 256 characters long" + } +} diff --git a/sdk/src/test/resources/mocks/errors/400_pagination_key_invalid.json b/sdk/src/test/resources/mocks/errors/400_pagination_key_invalid.json new file mode 100644 index 0000000..df559f9 --- /dev/null +++ b/sdk/src/test/resources/mocks/errors/400_pagination_key_invalid.json @@ -0,0 +1,6 @@ +{ + "error": { + "code": "RequestCannotBeParsed", + "message": "invalid pagination key" + } +} diff --git a/sdk/src/test/resources/mocks/errors/400_reverse_invalid.json b/sdk/src/test/resources/mocks/errors/400_reverse_invalid.json new file mode 100644 index 0000000..540800f --- /dev/null +++ b/sdk/src/test/resources/mocks/errors/400_reverse_invalid.json @@ -0,0 +1,6 @@ +{ + "error": { + "code": "RequestCannotBeParsed", + "message": "invalid reverse param" + } +} diff --git a/sdk/src/test/resources/mocks/errors/400_start_time_invalid.json b/sdk/src/test/resources/mocks/errors/400_start_time_invalid.json new file mode 100644 index 0000000..5d93f92 --- /dev/null +++ b/sdk/src/test/resources/mocks/errors/400_start_time_invalid.json @@ -0,0 +1,6 @@ +{ + "error": { + "code": "RequestCannotBeParsed", + "message": "invalid start time" + } +} \ No newline at end of file diff --git a/sdk/src/test/resources/mocks/get_event_200.json b/sdk/src/test/resources/mocks/get_event_200.json index fba76de..60013c0 100644 --- a/sdk/src/test/resources/mocks/get_event_200.json +++ b/sdk/src/test/resources/mocks/get_event_200.json @@ -180,7 +180,8 @@ "timezoneMismatch": false, "publicVPN": false, "auxiliaryMobile": false, - "osMismatch": false + "osMismatch": false, + "relay": false } } }, diff --git a/sdk/src/test/resources/mocks/get_event_search_200.json b/sdk/src/test/resources/mocks/get_event_search_200.json new file mode 100644 index 0000000..9d237eb --- /dev/null +++ b/sdk/src/test/resources/mocks/get_event_search_200.json @@ -0,0 +1,341 @@ +{ + "events": [ + { + "products": { + "identification": { + "data": { + "visitorId": "Ibk1527CUFmcnjLwIs4A9", + "requestId": "1708102555327.NLOjmg", + "incognito": true, + "linkedId": "somelinkedId", + "tag": {}, + "time": "2019-05-21T16:40:13Z", + "timestamp": 1582299576512, + "url": "https://www.example.com/login?hope{this{works[!", + "ip": "61.127.217.15", + "ipLocation": { + "accuracyRadius": 10, + "latitude": 49.982, + "longitude": 36.2566, + "postalCode": "61202", + "timezone": "Europe/Dusseldorf", + "city": { + "name": "Dusseldorf" + }, + "country": { + "code": "DE", + "name": "Germany" + }, + "continent": { + "code": "EU", + "name": "Europe" + }, + "subdivisions": [ + { + "isoCode": "63", + "name": "North Rhine-Westphalia" + } + ] + }, + "browserDetails": { + "browserName": "Chrome", + "browserMajorVersion": "74", + "browserFullVersion": "74.0.3729", + "os": "Windows", + "osVersion": "7", + "device": "Other", + "userAgent": "Mozilla/5.0 (Windows NT 6.1; Win64; x64) ...." + }, + "confidence": { + "score": 0.97 + }, + "visitorFound": false, + "firstSeenAt": { + "global": "2022-03-16T11:26:45.362Z", + "subscription": "2022-03-16T11:31:01.101Z" + }, + "lastSeenAt": { + "global": null, + "subscription": null + } + } + }, + "botd": { + "data": { + "bot": { + "result": "notDetected" + }, + "url": "https://www.example.com/login?hope{this{works}[!", + "ip": "61.127.217.15", + "time": "2019-05-21T16:40:13Z", + "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 YaBrowser/24.1.0.0 Safari/537.36", + "requestId": "1708102555327.NLOjmg" + } + }, + "rootApps": { + "data": { + "result": false + } + }, + "emulator": { + "data": { + "result": false + } + }, + "ipInfo": { + "data": { + "v4": { + "address": "94.142.239.124", + "geolocation": { + "accuracyRadius": 20, + "latitude": 50.05, + "longitude": 14.4, + "postalCode": "150 00", + "timezone": "Europe/Prague", + "city": { + "name": "Prague" + }, + "country": { + "code": "CZ", + "name": "Czechia" + }, + "continent": { + "code": "EU", + "name": "Europe" + }, + "subdivisions": [ + { + "isoCode": "10", + "name": "Hlavni mesto Praha" + } + ] + }, + "asn": { + "asn": "7922", + "name": "COMCAST-7922", + "network": "73.136.0.0/13" + }, + "datacenter": { + "result": true, + "name": "DediPath" + } + }, + "v6": { + "address": "2001:db8:3333:4444:5555:6666:7777:8888", + "geolocation": { + "accuracyRadius": 5, + "latitude": 49.982, + "longitude": 36.2566, + "postalCode": "10112", + "timezone": "Europe/Berlin", + "city": { + "name": "Berlin" + }, + "country": { + "code": "DE", + "name": "Germany" + }, + "continent": { + "code": "EU", + "name": "Europe" + }, + "subdivisions": [ + { + "isoCode": "BE", + "name": "Land Berlin" + } + ] + }, + "asn": { + "asn": "6805", + "name": "Telefonica Germany", + "network": "2a02:3100::/24" + }, + "datacenter": { + "result": false, + "name": "" + } + } + } + }, + "ipBlocklist": { + "data": { + "result": false, + "details": { + "emailSpam": false, + "attackSource": false + } + } + }, + "tor": { + "data": { + "result": false + } + }, + "vpn": { + "data": { + "result": false, + "confidence": "high", + "originTimezone": "Europe/Berlin", + "originCountry": "unknown", + "methods": { + "timezoneMismatch": false, + "publicVPN": false, + "auxiliaryMobile": false, + "osMismatch": false, + "relay": false + } + } + }, + "proxy": { + "data": { + "result": false + } + }, + "incognito": { + "data": { + "result": false + } + }, + "tampering": { + "data": { + "result": false, + "anomalyScore": 0.1955, + "antiDetectBrowser": false + } + }, + "clonedApp": { + "data": { + "result": false + } + }, + "factoryReset": { + "data": { + "time": "1970-01-01T00:00:00Z", + "timestamp": 0 + } + }, + "jailbroken": { + "data": { + "result": false + } + }, + "frida": { + "data": { + "result": false + } + }, + "privacySettings": { + "data": { + "result": false + } + }, + "virtualMachine": { + "data": { + "result": false + } + }, + "rawDeviceAttributes": { + "data": { + "architecture": { + "value": 127 + }, + "audio": { + "value": 35.73832903057337 + }, + "canvas": { + "value": { + "Winding": true, + "Geometry": "4dce9d6017c3e0c052a77252f29f2b1c", + "Text": "dd2474a56ff78c1de3e7a07070ba3b7d" + } + }, + "colorDepth": { + "value": 30 + }, + "colorGamut": { + "value": "p3" + }, + "contrast": { + "value": 0 + }, + "cookiesEnabled": { + "value": true + }, + "cpuClass": {}, + "fonts": { + "value": ["Arial Unicode MS", "Gill Sans", "Helvetica Neue", "Menlo"] + } + } + }, + "highActivity": { + "data": { + "result": false + } + }, + "locationSpoofing": { + "data": { + "result": false + } + }, + "remoteControl": { + "data": { + "result": false + } + }, + "velocity": { + "data": { + "distinctIp": { + "intervals": { + "5m": 1, + "1h": 1, + "24h": 1 + } + }, + "distinctLinkedId": {}, + "distinctCountry": { + "intervals": { + "5m": 1, + "1h": 2, + "24h": 2 + } + }, + "events": { + "intervals": { + "5m": 1, + "1h": 5, + "24h": 5 + } + }, + "ipEvents": { + "intervals": { + "5m": 1, + "1h": 5, + "24h": 5 + } + }, + "distinctIpByLinkedId": { + "intervals": { + "5m": 1, + "1h": 5, + "24h": 5 + } + }, + "distinctVisitorIdByLinkedId": { + "intervals": { + "5m": 1, + "1h": 5, + "24h": 5 + } + } + } + }, + "developerTools": { + "data": { + "result": false + } + } + }} + ], + "paginationKey": "1655373953086" +} diff --git a/sdk/src/test/resources/mocks/webhook.json b/sdk/src/test/resources/mocks/webhook.json index 2152b84..748d252 100644 --- a/sdk/src/test/resources/mocks/webhook.json +++ b/sdk/src/test/resources/mocks/webhook.json @@ -125,7 +125,8 @@ "timezoneMismatch": false, "publicVPN": false, "auxiliaryMobile": false, - "osMismatch": false + "osMismatch": false, + "relay": false } }, "proxy": {