Skip to content
Draft
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 docs/Event.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

# Event

Contains results from Fingerprint Identification and all active Smart Signals. Some Smart Signals are only supported for certain device types, these fields will be omitted for events not generated from the supported devices. Consult the [Smart Signals reference](https://docs.fingerprint.com/docs/smart-signals-reference) for more details.
Contains results from Fingerprint Identification and all active Smart Signals, or from the Automation Intelligence API. Check `source` to see which properties can be present: - `device` - generated by the JS agent or a mobile SDK running on an end-user device. Contains Identification (`visitor_id`) and Smart Signals. Some Smart Signals are only supported for certain device types, these fields will be omitted for events not generated from the supported devices. - `edge` - generated by the Automation Intelligence API (`/edge` endpoint). Contains only IP and bot analysis, never Identification or Smart Signals derived from device telemetry. Events stored before `source` was added don't have it; treat them as `device`. Consult the [Smart Signals reference](https://docs.fingerprint.com/docs/smart-signals-reference) for more details.

## Properties

Expand Down
27 changes: 20 additions & 7 deletions res/fingerprint-server-api.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -1204,6 +1204,11 @@ components:
enum:
- device
- edge
EnvironmentId:
type: string
examples:
- ae_47abaca3db2c7c43
description: Environment ID of the event.
Url:
type: string
examples:
Expand Down Expand Up @@ -1720,11 +1725,6 @@ components:
enum:
- partially_completed
- completed
EnvironmentId:
type: string
examples:
- ae_47abaca3db2c7c43
description: Environment ID of the event.
Suspect:
type: boolean
description: >-
Expand Down Expand Up @@ -3146,11 +3146,24 @@ components:
team](https://fingerprint.com/support/).
Event:
type: object
description: >-
description: >
Contains results from Fingerprint Identification and all active Smart
Signals, or from the Automation Intelligence API. Check `source` to see
which properties can be present:

- `device` - generated by the JS agent or a mobile SDK running on an
end-user device. Contains Identification (`visitor_id`) and Smart
Signals. Some Smart Signals are only supported for certain device types,
these fields will be omitted for events not generated from the supported
devices. Consult the [Smart Signals
devices.

- `edge` - generated by the Automation Intelligence API (`/edge`
endpoint). Contains only IP and bot analysis, never Identification or
Smart Signals derived from device telemetry.


Events stored before `source` was added don't have it; treat them as
`device`. Consult the [Smart Signals
reference](https://docs.fingerprint.com/docs/smart-signals-reference)
for more details.
required:
Expand Down
2 changes: 1 addition & 1 deletion sdk/src/main/java/com/fingerprint/v4/model/Event.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
import java.util.Objects;

/**
* Contains results from Fingerprint Identification and all active Smart Signals. Some Smart Signals are only supported for certain device types, these fields will be omitted for events not generated from the supported devices. Consult the [Smart Signals reference](https://docs.fingerprint.com/docs/smart-signals-reference) for more details.
* Contains results from Fingerprint Identification and all active Smart Signals, or from the Automation Intelligence API. Check `source` to see which properties can be present: - `device` - generated by the JS agent or a mobile SDK running on an end-user device. Contains Identification (`visitor_id`) and Smart Signals. Some Smart Signals are only supported for certain device types, these fields will be omitted for events not generated from the supported devices. - `edge` - generated by the Automation Intelligence API (`/edge` endpoint). Contains only IP and bot analysis, never Identification or Smart Signals derived from device telemetry. Events stored before `source` was added don't have it; treat them as `device`. Consult the [Smart Signals reference](https://docs.fingerprint.com/docs/smart-signals-reference) for more details.
*/
@JsonPropertyOrder({
Event.JSON_PROPERTY_EVENT_ID,
Expand Down
51 changes: 51 additions & 0 deletions sdk/src/test/java/com/fingerprint/v4/SerializationTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@

import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertInstanceOf;
import static org.junit.jupiter.api.Assertions.assertNotEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertNull;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
Expand All @@ -14,6 +16,7 @@
import com.fingerprint.v4.model.ErrorResponse;
import com.fingerprint.v4.model.Event;
import com.fingerprint.v4.model.EventRuleAction;
import com.fingerprint.v4.model.EventSource;
import com.fingerprint.v4.sdk.JSON;
import java.io.File;
import java.io.IOException;
Expand Down Expand Up @@ -104,6 +107,54 @@ public void deserializeEventWithUnknownRuleActionTypeValue() throws IOException
assertInstanceOf(EventRuleAction.UnknownEventRuleAction.class, event.getRuleAction());
}

@Test
public void deserializeEventWithoutSource() throws IOException {
ObjectMapper sdkObjectMapper = JSON.getDefault().getMapper();

ObjectNode eventNode =
sdkObjectMapper.readValue(
getFileAsIOStream(EVENTS_DIR + "/get_event_200.json"), ObjectNode.class);
eventNode.remove("source");

Event event = sdkObjectMapper.treeToValue(eventNode, Event.class);

assertNull(event.getSource());
assertNotNull(event.getIdentification());
assertEquals(eventNode.get("event_id").asText(), event.getEventId());
assertFalse(sdkObjectMapper.writeValueAsString(event).contains("\"source\""));
}

@Test
public void deserializeEdgeEvent() throws IOException {
ObjectMapper sdkObjectMapper = JSON.getDefault().getMapper();

Event event =
sdkObjectMapper.readValue(
getFileAsIOStream(EVENTS_DIR + "/get_event_with_edge_200.json"), Event.class);

assertEquals(EventSource.EDGE, event.getSource());
assertNull(event.getIdentification());
assertNotNull(event.getIpInfo());
assertNotNull(event.getBotInfo());
assertEquals(
"edge",
sdkObjectMapper.readTree(sdkObjectMapper.writeValueAsString(event)).get("source").asText());
}

@Test
public void deserializeEventWithUnknownSource() throws IOException {
ObjectMapper sdkObjectMapper = JSON.getDefault().getMapper();

ObjectNode eventNode =
sdkObjectMapper.readValue(
getFileAsIOStream(EVENTS_DIR + "/get_event_200.json"), ObjectNode.class);
eventNode.put("source", "something_new");

Event event = sdkObjectMapper.treeToValue(eventNode, Event.class);

assertEquals(EventSource.UNSUPPORTED_VALUE_SDK_UPGRADE_REQUIRED, event.getSource());
}

@TestFactory
public Stream<DynamicTest> deserializeErrorResponses() {
ObjectMapper sdkObjectMapper = JSON.getDefault().getMapper();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"error": {
"code": "failed",
"message": "gateway timeout"
}
}
57 changes: 47 additions & 10 deletions sdk/src/test/resources/mocks/webhook/webhook_event.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,14 @@
"tags": {},
"timestamp": 1708102555327,
"event_id": "1708102555327.NLOjmg",
"source": "device",
"incremental_identification_status": "completed",
"url": "https://www.example.com/login?hope{this{works[!",
"ip_address": "61.127.217.15",
"user_agent": "Mozilla/5.0 (Windows NT 6.1; Win64; x64) ....",
"device": "Other",
"os": "Windows",
"os_version": "7",
"client_referrer": "https://example.com/blog/my-article",
"browser_details": {
"browser_name": "Chrome",
Expand All @@ -26,14 +31,14 @@
"last_seen_at": 1708102555327
},
"supplementary_id_high_recall": {
"visitor_id": "3HNey93AkBW6CRbxV6xP",
"visitor_id": "0jnGMkPYXX37DqVa4ZIO3f_hr",
"visitor_found": true,
"confidence": {
"score": 0.97,
"version": "1.1"
"score": 0,
"version": "Not Supported"
},
"first_seen_at": 1708102555327,
"last_seen_at": 1708102555327
"first_seen_at": 1778086556130,
"last_seen_at": 1778604975494
},
"proximity": {
"id": "w1aTfd4MCvl",
Expand Down Expand Up @@ -111,19 +116,24 @@
"last_seen_at": 1708102555327,
"provider": "Massive"
},
"proxy_ml_score": 0.2,
"vpn": false,
"vpn_confidence": "high",
"vpn_ml_score": 0.2,
"vpn_origin_timezone": "Europe/Berlin",
"vpn_origin_country": "unknown",
"vpn_methods": {
"timezone_mismatch": false,
"public_vpn": false,
"auxiliary_mobile": false,
"os_mismatch": false,
"relay": false
"relay": false,
"ml_prediction": false
},
"incognito": false,
"tampering": false,
"tampering_confidence": "high",
"tampering_ml_score": 0.3231,
"tampering_details": {
"anomaly_score": 0.1955,
"anti_detect_browser": false
Expand All @@ -143,6 +153,11 @@
"1_hour": 1,
"24_hours": 1
},
"distinct_linked_id": {
"5_minutes": 1,
"1_hour": 5,
"24_hours": 5
},
"distinct_country": {
"5_minutes": 1,
"1_hour": 2,
Expand Down Expand Up @@ -170,6 +185,11 @@
}
},
"developer_tools": false,
"device_details": {
"device_manufacturer": "samsung",
"device_model": "SM-G991U",
"os_version": "13"
},
"mitm_attack": false,
"sdk": {
"platform": "js",
Expand All @@ -187,8 +207,6 @@
},
"replayed": false,
"high_activity_device": false,
"rare_device": false,
"rare_device_percentile_bucket": "<p95",
"raw_device_attributes": {
"math": "5f030fa7d2e5f9f757bfaf81642eb1a6",
"vendor": "Google Inc.",
Expand Down Expand Up @@ -281,6 +299,25 @@
"local_storage": true,
"session_storage": true,
"date_time_locale": "en-US",
"audio": 124.04347745512496
}
"audio": 124.04347745512496,
"keyboard_layout_hash": "691e3845c85c202a1514b6fd7ef17065",
"keyboard_layout_name": "en-US",
"battery_charging": true,
"battery_level": 80,
"battery_low_power_mode": true,
"timezone_offset": "-03:00",
"font_hash": "bb4d842593877975d45017c603ff5994",
"device_manufacturer": "samsung",
"device_model": "SM-S921U"
},
"rare_device": false,
"rare_device_percentile_bucket": "<p95",
"labels": [
{
"label": "fraud",
"prediction": false,
"ml_score": 0.01
}
],
"active_call": false
}
Loading