From 7a252141e24af42aed0a99051dc0bcfd83ce0ef8 Mon Sep 17 00:00:00 2001 From: JuroUhlar Date: Tue, 25 Mar 2025 15:53:19 +0000 Subject: [PATCH 1/3] feat: update OpenAPI schema --- .changeset/add-mitmattack-smartsignal.md | 5 + .schema-version | 2 +- README.md | 3 + docs/FingerprintApi.md | 4 +- docs/MitMAttack.md | 9 ++ docs/ProductMitMAttack.md | 10 ++ docs/Products.md | 1 + docs/Webhook.md | 1 + docs/WebhookMitMAttack.md | 9 ++ fingerprint_pro_server_api_sdk/__init__.py | 3 + .../api/fingerprint_api.py | 4 +- .../models/__init__.py | 3 + .../models/mit_m_attack.py | 70 ++++++++++++++ .../models/product_mit_m_attack.py | 94 +++++++++++++++++++ .../models/products.py | 34 ++++++- .../models/webhook.py | 34 ++++++- .../models/webhook_mit_m_attack.py | 69 ++++++++++++++ res/fingerprint-server-api.yaml | 57 ++++++++++- test/mocks/get_event_200.json | 5 + test/mocks/get_event_200_all_errors.json | 6 ++ .../get_event_200_with_broken_format.json | 5 + .../get_event_200_with_unknown_field.json | 5 + test/mocks/get_event_search_200.json | 5 + test/mocks/webhook.json | 3 + 24 files changed, 426 insertions(+), 15 deletions(-) create mode 100644 .changeset/add-mitmattack-smartsignal.md create mode 100644 docs/MitMAttack.md create mode 100644 docs/ProductMitMAttack.md create mode 100644 docs/WebhookMitMAttack.md create mode 100644 fingerprint_pro_server_api_sdk/models/mit_m_attack.py create mode 100644 fingerprint_pro_server_api_sdk/models/product_mit_m_attack.py create mode 100644 fingerprint_pro_server_api_sdk/models/webhook_mit_m_attack.py diff --git a/.changeset/add-mitmattack-smartsignal.md b/.changeset/add-mitmattack-smartsignal.md new file mode 100644 index 00000000..37d28f8c --- /dev/null +++ b/.changeset/add-mitmattack-smartsignal.md @@ -0,0 +1,5 @@ +--- +"fingerprint-pro-server-api-openapi": minor +--- + +Add `mitmAttack` (man-in-the-middle attack) Smart Signal. diff --git a/.schema-version b/.schema-version index a6316f06..fa49670c 100644 --- a/.schema-version +++ b/.schema-version @@ -1 +1 @@ -v2.3.0 \ No newline at end of file +v2.4.0 \ No newline at end of file diff --git a/README.md b/README.md index 9746b05d..442a53e8 100644 --- a/README.md +++ b/README.md @@ -328,6 +328,7 @@ Class | Method | HTTP request | Description - [Incognito](docs/Incognito.md) - [Jailbroken](docs/Jailbroken.md) - [LocationSpoofing](docs/LocationSpoofing.md) + - [MitMAttack](docs/MitMAttack.md) - [PrivacySettings](docs/PrivacySettings.md) - [ProductBotd](docs/ProductBotd.md) - [ProductClonedApp](docs/ProductClonedApp.md) @@ -342,6 +343,7 @@ Class | Method | HTTP request | Description - [ProductIncognito](docs/ProductIncognito.md) - [ProductJailbroken](docs/ProductJailbroken.md) - [ProductLocationSpoofing](docs/ProductLocationSpoofing.md) + - [ProductMitMAttack](docs/ProductMitMAttack.md) - [ProductPrivacySettings](docs/ProductPrivacySettings.md) - [ProductProxy](docs/ProductProxy.md) - [ProductRawDeviceAttributes](docs/ProductRawDeviceAttributes.md) @@ -388,6 +390,7 @@ Class | Method | HTTP request | Description - [WebhookIPInfo](docs/WebhookIPInfo.md) - [WebhookJailbroken](docs/WebhookJailbroken.md) - [WebhookLocationSpoofing](docs/WebhookLocationSpoofing.md) + - [WebhookMitMAttack](docs/WebhookMitMAttack.md) - [WebhookPrivacySettings](docs/WebhookPrivacySettings.md) - [WebhookProxy](docs/WebhookProxy.md) - [WebhookRawDeviceAttributes](docs/WebhookRawDeviceAttributes.md) diff --git a/docs/FingerprintApi.md b/docs/FingerprintApi.md index a15ac001..ba90afa9 100644 --- a/docs/FingerprintApi.md +++ b/docs/FingerprintApi.md @@ -179,7 +179,7 @@ configuration = fingerprint_pro_server_api_sdk.Configuration(api_key="SECRET_API # create an instance of the API class api_instance = fingerprint_pro_server_api_sdk.FingerprintApi(configuration) -visitor_id = 'visitor_id_example' # str | Unique [visitor identifier](https://dev.fingerprint.com/reference/get-function#visitorid) issued by Fingerprint Pro. +visitor_id = 'visitor_id_example' # str | Unique [visitor identifier](https://dev.fingerprint.com/reference/get-function#visitorid) issued by Fingerprint Pro.\\ request_id = 'request_id_example' # str | Filter visits by `requestId`. Every identification request has a unique identifier associated with it called `requestId`. This identifier is returned to the client in the identification [result](https://dev.fingerprint.com/reference/get-function#requestid). When you filter visits by `requestId`, only one visit will be returned. (optional) linked_id = 'linked_id_example' # str | Filter visits by your custom identifier. You can use [`linkedId`](https://dev.fingerprint.com/reference/get-function#linkedid) to associate identification requests with your own identifier, for example: session ID, purchase ID, or transaction ID. You can then use this `linked_id` parameter to retrieve all events associated with your custom identifier. (optional) limit = 56 # int | Limit scanned results. For performance reasons, the API first scans some number of events before filtering them. Use `limit` to specify how many events are scanned before they are filtered by `requestId` or `linkedId`. Results are always returned sorted by the timestamp (most recent first). By default, the most recent 100 visits are scanned, the maximum is 500. (optional) @@ -198,7 +198,7 @@ except ApiException as e: Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- - **visitor_id** | **str**| Unique [visitor identifier](https://dev.fingerprint.com/reference/get-function#visitorid) issued by Fingerprint Pro. | + **visitor_id** | **str**| Unique [visitor identifier](https://dev.fingerprint.com/reference/get-function#visitorid) issued by Fingerprint Pro.\\ | **request_id** | **str**| Filter visits by `requestId`. Every identification request has a unique identifier associated with it called `requestId`. This identifier is returned to the client in the identification [result](https://dev.fingerprint.com/reference/get-function#requestid). When you filter visits by `requestId`, only one visit will be returned. | [optional] **linked_id** | **str**| Filter visits by your custom identifier. You can use [`linkedId`](https://dev.fingerprint.com/reference/get-function#linkedid) to associate identification requests with your own identifier, for example: session ID, purchase ID, or transaction ID. You can then use this `linked_id` parameter to retrieve all events associated with your custom identifier. | [optional] **limit** | **int**| Limit scanned results. For performance reasons, the API first scans some number of events before filtering them. Use `limit` to specify how many events are scanned before they are filtered by `requestId` or `linkedId`. Results are always returned sorted by the timestamp (most recent first). By default, the most recent 100 visits are scanned, the maximum is 500. | [optional] diff --git a/docs/MitMAttack.md b/docs/MitMAttack.md new file mode 100644 index 00000000..7168f1b5 --- /dev/null +++ b/docs/MitMAttack.md @@ -0,0 +1,9 @@ +# MitMAttack + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**result** | **bool** | * `true` - When requests made from your users' mobile devices to Fingerprint servers have been intercepted and potentially modified. * `false` - Otherwise or when the request originated from a browser. See [MitM Attack Detection](https://dev.fingerprint.com/docs/smart-signals-reference#mitm-attack-detection) to learn more about this Smart Signal. | + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + diff --git a/docs/ProductMitMAttack.md b/docs/ProductMitMAttack.md new file mode 100644 index 00000000..91ad8c7e --- /dev/null +++ b/docs/ProductMitMAttack.md @@ -0,0 +1,10 @@ +# ProductMitMAttack + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**data** | [**MitMAttack**](MitMAttack.md) | | [optional] +**error** | [**Error**](Error.md) | | [optional] + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + diff --git a/docs/Products.md b/docs/Products.md index 8e885397..1c38353a 100644 --- a/docs/Products.md +++ b/docs/Products.md @@ -29,6 +29,7 @@ Name | Type | Description | Notes **remote_control** | [**ProductRemoteControl**](ProductRemoteControl.md) | | [optional] **velocity** | [**ProductVelocity**](ProductVelocity.md) | | [optional] **developer_tools** | [**ProductDeveloperTools**](ProductDeveloperTools.md) | | [optional] +**mitm_attack** | [**ProductMitMAttack**](ProductMitMAttack.md) | | [optional] [[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) diff --git a/docs/Webhook.md b/docs/Webhook.md index 9de4a3a9..19b89753 100644 --- a/docs/Webhook.md +++ b/docs/Webhook.md @@ -43,6 +43,7 @@ Name | Type | Description | Notes **remote_control** | [**WebhookRemoteControl**](WebhookRemoteControl.md) | | [optional] **velocity** | [**WebhookVelocity**](WebhookVelocity.md) | | [optional] **developer_tools** | [**WebhookDeveloperTools**](WebhookDeveloperTools.md) | | [optional] +**mitm_attack** | [**WebhookMitMAttack**](WebhookMitMAttack.md) | | [optional] [[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) diff --git a/docs/WebhookMitMAttack.md b/docs/WebhookMitMAttack.md new file mode 100644 index 00000000..3ff714c6 --- /dev/null +++ b/docs/WebhookMitMAttack.md @@ -0,0 +1,9 @@ +# WebhookMitMAttack + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**result** | **bool** | * `true` - When requests made from your users' mobile devices to Fingerprint servers have been intercepted and potentially modified. * `false` - Otherwise or when the request originated from a browser. See [MitM Attack Detection](https://dev.fingerprint.com/docs/smart-signals-overview#mitm-attack-detection) to learn more about this Smart Signal. | [optional] + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + diff --git a/fingerprint_pro_server_api_sdk/__init__.py b/fingerprint_pro_server_api_sdk/__init__.py index baaa97f3..5f53d213 100644 --- a/fingerprint_pro_server_api_sdk/__init__.py +++ b/fingerprint_pro_server_api_sdk/__init__.py @@ -56,6 +56,7 @@ from fingerprint_pro_server_api_sdk.models.incognito import Incognito from fingerprint_pro_server_api_sdk.models.jailbroken import Jailbroken from fingerprint_pro_server_api_sdk.models.location_spoofing import LocationSpoofing +from fingerprint_pro_server_api_sdk.models.mit_m_attack import MitMAttack from fingerprint_pro_server_api_sdk.models.privacy_settings import PrivacySettings from fingerprint_pro_server_api_sdk.models.product_botd import ProductBotd from fingerprint_pro_server_api_sdk.models.product_cloned_app import ProductClonedApp @@ -70,6 +71,7 @@ from fingerprint_pro_server_api_sdk.models.product_incognito import ProductIncognito from fingerprint_pro_server_api_sdk.models.product_jailbroken import ProductJailbroken from fingerprint_pro_server_api_sdk.models.product_location_spoofing import ProductLocationSpoofing +from fingerprint_pro_server_api_sdk.models.product_mit_m_attack import ProductMitMAttack from fingerprint_pro_server_api_sdk.models.product_privacy_settings import ProductPrivacySettings from fingerprint_pro_server_api_sdk.models.product_proxy import ProductProxy from fingerprint_pro_server_api_sdk.models.product_raw_device_attributes import ProductRawDeviceAttributes @@ -116,6 +118,7 @@ from fingerprint_pro_server_api_sdk.models.webhook_ip_info import WebhookIPInfo from fingerprint_pro_server_api_sdk.models.webhook_jailbroken import WebhookJailbroken from fingerprint_pro_server_api_sdk.models.webhook_location_spoofing import WebhookLocationSpoofing +from fingerprint_pro_server_api_sdk.models.webhook_mit_m_attack import WebhookMitMAttack from fingerprint_pro_server_api_sdk.models.webhook_privacy_settings import WebhookPrivacySettings from fingerprint_pro_server_api_sdk.models.webhook_proxy import WebhookProxy from fingerprint_pro_server_api_sdk.models.webhook_raw_device_attributes import WebhookRawDeviceAttributes diff --git a/fingerprint_pro_server_api_sdk/api/fingerprint_api.py b/fingerprint_pro_server_api_sdk/api/fingerprint_api.py index a69e3b5d..be08ebbc 100644 --- a/fingerprint_pro_server_api_sdk/api/fingerprint_api.py +++ b/fingerprint_pro_server_api_sdk/api/fingerprint_api.py @@ -374,7 +374,7 @@ def get_visits(self, visitor_id: str, **kwargs) -> Union[VisitorsGetResponse, As >>> result = thread.get() :param async_req bool - :param visitor_id: Unique [visitor identifier](https://dev.fingerprint.com/reference/get-function#visitorid) issued by Fingerprint Pro. (required) + :param visitor_id: Unique [visitor identifier](https://dev.fingerprint.com/reference/get-function#visitorid) issued by Fingerprint Pro.\\ (required) :param request_id: Filter visits by `requestId`. Every identification request has a unique identifier associated with it called `requestId`. This identifier is returned to the client in the identification [result](https://dev.fingerprint.com/reference/get-function#requestid). When you filter visits by `requestId`, only one visit will be returned. :param linked_id: Filter visits by your custom identifier. You can use [`linkedId`](https://dev.fingerprint.com/reference/get-function#linkedid) to associate identification requests with your own identifier, for example: session ID, purchase ID, or transaction ID. You can then use this `linked_id` parameter to retrieve all events associated with your custom identifier. :param limit: Limit scanned results. For performance reasons, the API first scans some number of events before filtering them. Use `limit` to specify how many events are scanned before they are filtered by `requestId` or `linkedId`. Results are always returned sorted by the timestamp (most recent first). By default, the most recent 100 visits are scanned, the maximum is 500. @@ -401,7 +401,7 @@ def get_visits_with_http_info(self, visitor_id: str, **kwargs): # noqa: E501 >>> result = thread.get() :param async_req bool - :param str visitor_id: Unique [visitor identifier](https://dev.fingerprint.com/reference/get-function#visitorid) issued by Fingerprint Pro. (required) + :param str visitor_id: Unique [visitor identifier](https://dev.fingerprint.com/reference/get-function#visitorid) issued by Fingerprint Pro.\\ (required) :param str request_id: Filter visits by `requestId`. Every identification request has a unique identifier associated with it called `requestId`. This identifier is returned to the client in the identification [result](https://dev.fingerprint.com/reference/get-function#requestid). When you filter visits by `requestId`, only one visit will be returned. :param str linked_id: Filter visits by your custom identifier. You can use [`linkedId`](https://dev.fingerprint.com/reference/get-function#linkedid) to associate identification requests with your own identifier, for example: session ID, purchase ID, or transaction ID. You can then use this `linked_id` parameter to retrieve all events associated with your custom identifier. :param int limit: Limit scanned results. For performance reasons, the API first scans some number of events before filtering them. Use `limit` to specify how many events are scanned before they are filtered by `requestId` or `linkedId`. Results are always returned sorted by the timestamp (most recent first). By default, the most recent 100 visits are scanned, the maximum is 500. diff --git a/fingerprint_pro_server_api_sdk/models/__init__.py b/fingerprint_pro_server_api_sdk/models/__init__.py index c6c22b4f..0fb230af 100644 --- a/fingerprint_pro_server_api_sdk/models/__init__.py +++ b/fingerprint_pro_server_api_sdk/models/__init__.py @@ -48,6 +48,7 @@ from fingerprint_pro_server_api_sdk.models.incognito import Incognito from fingerprint_pro_server_api_sdk.models.jailbroken import Jailbroken from fingerprint_pro_server_api_sdk.models.location_spoofing import LocationSpoofing +from fingerprint_pro_server_api_sdk.models.mit_m_attack import MitMAttack from fingerprint_pro_server_api_sdk.models.privacy_settings import PrivacySettings from fingerprint_pro_server_api_sdk.models.product_botd import ProductBotd from fingerprint_pro_server_api_sdk.models.product_cloned_app import ProductClonedApp @@ -62,6 +63,7 @@ from fingerprint_pro_server_api_sdk.models.product_incognito import ProductIncognito from fingerprint_pro_server_api_sdk.models.product_jailbroken import ProductJailbroken from fingerprint_pro_server_api_sdk.models.product_location_spoofing import ProductLocationSpoofing +from fingerprint_pro_server_api_sdk.models.product_mit_m_attack import ProductMitMAttack from fingerprint_pro_server_api_sdk.models.product_privacy_settings import ProductPrivacySettings from fingerprint_pro_server_api_sdk.models.product_proxy import ProductProxy from fingerprint_pro_server_api_sdk.models.product_raw_device_attributes import ProductRawDeviceAttributes @@ -108,6 +110,7 @@ from fingerprint_pro_server_api_sdk.models.webhook_ip_info import WebhookIPInfo from fingerprint_pro_server_api_sdk.models.webhook_jailbroken import WebhookJailbroken from fingerprint_pro_server_api_sdk.models.webhook_location_spoofing import WebhookLocationSpoofing +from fingerprint_pro_server_api_sdk.models.webhook_mit_m_attack import WebhookMitMAttack from fingerprint_pro_server_api_sdk.models.webhook_privacy_settings import WebhookPrivacySettings from fingerprint_pro_server_api_sdk.models.webhook_proxy import WebhookProxy from fingerprint_pro_server_api_sdk.models.webhook_raw_device_attributes import WebhookRawDeviceAttributes diff --git a/fingerprint_pro_server_api_sdk/models/mit_m_attack.py b/fingerprint_pro_server_api_sdk/models/mit_m_attack.py new file mode 100644 index 00000000..b9a21a73 --- /dev/null +++ b/fingerprint_pro_server_api_sdk/models/mit_m_attack.py @@ -0,0 +1,70 @@ +# coding: utf-8 + +""" + Fingerprint Pro Server API + + Fingerprint Pro Server API allows you to get information about visitors and about individual events in a server environment. It can be used for data exports, decision-making, and data analysis scenarios. Server API is intended for server-side usage, it's not intended to be used from the client side, whether it's a browser or a mobile device. # noqa: E501 + + OpenAPI spec version: 3 + Contact: support@fingerprint.com + Generated by: https://github.com/swagger-api/swagger-codegen.git +""" + +import re # noqa: F401 +from typing import Dict, List, Optional # noqa: F401 +from fingerprint_pro_server_api_sdk.base_model import BaseModel + + +class MitMAttack(BaseModel): + """NOTE: This class is auto generated by the swagger code generator program. + + Do not edit the class manually. + """ + """ + Attributes: + swagger_types (dict): The key is attribute name + and the value is attribute type. + attribute_map (dict): The key is attribute name + and the value is json key in definition. + """ + swagger_types = { + 'result': 'bool' + } + + nullable_map = { + 'result': False + } + + attribute_map = { + 'result': 'result' + } + + def __init__(self, result=None): # noqa: E501 + """MitMAttack - a model defined in Swagger""" # noqa: E501 + self._result = None + self.discriminator = None + self.result = result + + @property + def result(self) -> bool: + """Gets the result of this MitMAttack. # noqa: E501 + + * `true` - When requests made from your users' mobile devices to Fingerprint servers have been intercepted and potentially modified. * `false` - Otherwise or when the request originated from a browser. See [MitM Attack Detection](https://dev.fingerprint.com/docs/smart-signals-reference#mitm-attack-detection) to learn more about this Smart Signal. # noqa: E501 + + :return: The result of this MitMAttack. # noqa: E501 + """ + return self._result + + @result.setter + def result(self, result: bool): + """Sets the result of this MitMAttack. + + * `true` - When requests made from your users' mobile devices to Fingerprint servers have been intercepted and potentially modified. * `false` - Otherwise or when the request originated from a browser. See [MitM Attack Detection](https://dev.fingerprint.com/docs/smart-signals-reference#mitm-attack-detection) to learn more about this Smart Signal. # noqa: E501 + + :param result: The result of this MitMAttack. # noqa: E501 + """ + if result is None: + raise ValueError("Invalid value for `result`, must not be `None`") # noqa: E501 + + self._result = result + diff --git a/fingerprint_pro_server_api_sdk/models/product_mit_m_attack.py b/fingerprint_pro_server_api_sdk/models/product_mit_m_attack.py new file mode 100644 index 00000000..e14ca7d8 --- /dev/null +++ b/fingerprint_pro_server_api_sdk/models/product_mit_m_attack.py @@ -0,0 +1,94 @@ +# coding: utf-8 + +""" + Fingerprint Pro Server API + + Fingerprint Pro Server API allows you to get information about visitors and about individual events in a server environment. It can be used for data exports, decision-making, and data analysis scenarios. Server API is intended for server-side usage, it's not intended to be used from the client side, whether it's a browser or a mobile device. # noqa: E501 + + OpenAPI spec version: 3 + Contact: support@fingerprint.com + Generated by: https://github.com/swagger-api/swagger-codegen.git +""" + +import re # noqa: F401 +from typing import Dict, List, Optional # noqa: F401 +from fingerprint_pro_server_api_sdk.base_model import BaseModel +from fingerprint_pro_server_api_sdk.models.mit_m_attack import MitMAttack +from fingerprint_pro_server_api_sdk.models.error import Error + + +class ProductMitMAttack(BaseModel): + """NOTE: This class is auto generated by the swagger code generator program. + + Do not edit the class manually. + """ + """ + Attributes: + swagger_types (dict): The key is attribute name + and the value is attribute type. + attribute_map (dict): The key is attribute name + and the value is json key in definition. + """ + swagger_types = { + 'data': 'MitMAttack', + 'error': 'Error' + } + + nullable_map = { + 'data': False, + 'error': False + } + + attribute_map = { + 'data': 'data', + 'error': 'error' + } + + def __init__(self, data=None, error=None): # noqa: E501 + """ProductMitMAttack - a model defined in Swagger""" # noqa: E501 + self._data = None + self._error = None + self.discriminator = None + if data is not None: + self.data = data + if error is not None: + self.error = error + + @property + def data(self) -> Optional[MitMAttack]: + """Gets the data of this ProductMitMAttack. # noqa: E501 + + + :return: The data of this ProductMitMAttack. # noqa: E501 + """ + return self._data + + @data.setter + def data(self, data: Optional[MitMAttack]): + """Sets the data of this ProductMitMAttack. + + + :param data: The data of this ProductMitMAttack. # noqa: E501 + """ + + self._data = data + + @property + def error(self) -> Optional[Error]: + """Gets the error of this ProductMitMAttack. # noqa: E501 + + + :return: The error of this ProductMitMAttack. # noqa: E501 + """ + return self._error + + @error.setter + def error(self, error: Optional[Error]): + """Sets the error of this ProductMitMAttack. + + + :param error: The error of this ProductMitMAttack. # noqa: E501 + """ + + self._error = error + diff --git a/fingerprint_pro_server_api_sdk/models/products.py b/fingerprint_pro_server_api_sdk/models/products.py index 2ec11401..a4406d6e 100644 --- a/fingerprint_pro_server_api_sdk/models/products.py +++ b/fingerprint_pro_server_api_sdk/models/products.py @@ -37,6 +37,7 @@ from fingerprint_pro_server_api_sdk.models.product_remote_control import ProductRemoteControl from fingerprint_pro_server_api_sdk.models.product_velocity import ProductVelocity from fingerprint_pro_server_api_sdk.models.product_developer_tools import ProductDeveloperTools +from fingerprint_pro_server_api_sdk.models.product_mit_m_attack import ProductMitMAttack class Products(BaseModel): @@ -78,7 +79,8 @@ class Products(BaseModel): 'suspect_score': 'ProductSuspectScore', 'remote_control': 'ProductRemoteControl', 'velocity': 'ProductVelocity', - 'developer_tools': 'ProductDeveloperTools' + 'developer_tools': 'ProductDeveloperTools', + 'mitm_attack': 'ProductMitMAttack' } nullable_map = { @@ -105,7 +107,8 @@ class Products(BaseModel): 'suspect_score': False, 'remote_control': False, 'velocity': False, - 'developer_tools': False + 'developer_tools': False, + 'mitm_attack': False } attribute_map = { @@ -132,10 +135,11 @@ class Products(BaseModel): 'suspect_score': 'suspectScore', 'remote_control': 'remoteControl', 'velocity': 'velocity', - 'developer_tools': 'developerTools' + 'developer_tools': 'developerTools', + 'mitm_attack': 'mitmAttack' } - def __init__(self, identification=None, botd=None, root_apps=None, emulator=None, ip_info=None, ip_blocklist=None, tor=None, vpn=None, proxy=None, incognito=None, tampering=None, cloned_app=None, factory_reset=None, jailbroken=None, frida=None, privacy_settings=None, virtual_machine=None, raw_device_attributes=None, high_activity=None, location_spoofing=None, suspect_score=None, remote_control=None, velocity=None, developer_tools=None): # noqa: E501 + def __init__(self, identification=None, botd=None, root_apps=None, emulator=None, ip_info=None, ip_blocklist=None, tor=None, vpn=None, proxy=None, incognito=None, tampering=None, cloned_app=None, factory_reset=None, jailbroken=None, frida=None, privacy_settings=None, virtual_machine=None, raw_device_attributes=None, high_activity=None, location_spoofing=None, suspect_score=None, remote_control=None, velocity=None, developer_tools=None, mitm_attack=None): # noqa: E501 """Products - a model defined in Swagger""" # noqa: E501 self._identification = None self._botd = None @@ -161,6 +165,7 @@ def __init__(self, identification=None, botd=None, root_apps=None, emulator=None self._remote_control = None self._velocity = None self._developer_tools = None + self._mitm_attack = None self.discriminator = None if identification is not None: self.identification = identification @@ -210,6 +215,8 @@ def __init__(self, identification=None, botd=None, root_apps=None, emulator=None self.velocity = velocity if developer_tools is not None: self.developer_tools = developer_tools + if mitm_attack is not None: + self.mitm_attack = mitm_attack @property def identification(self) -> Optional[ProductIdentification]: @@ -667,3 +674,22 @@ def developer_tools(self, developer_tools: Optional[ProductDeveloperTools]): self._developer_tools = developer_tools + @property + def mitm_attack(self) -> Optional[ProductMitMAttack]: + """Gets the mitm_attack of this Products. # noqa: E501 + + + :return: The mitm_attack of this Products. # noqa: E501 + """ + return self._mitm_attack + + @mitm_attack.setter + def mitm_attack(self, mitm_attack: Optional[ProductMitMAttack]): + """Sets the mitm_attack of this Products. + + + :param mitm_attack: The mitm_attack of this Products. # noqa: E501 + """ + + self._mitm_attack = mitm_attack + diff --git a/fingerprint_pro_server_api_sdk/models/webhook.py b/fingerprint_pro_server_api_sdk/models/webhook.py index a1dfb853..032144b1 100644 --- a/fingerprint_pro_server_api_sdk/models/webhook.py +++ b/fingerprint_pro_server_api_sdk/models/webhook.py @@ -43,6 +43,7 @@ from fingerprint_pro_server_api_sdk.models.webhook_remote_control import WebhookRemoteControl from fingerprint_pro_server_api_sdk.models.webhook_velocity import WebhookVelocity from fingerprint_pro_server_api_sdk.models.webhook_developer_tools import WebhookDeveloperTools +from fingerprint_pro_server_api_sdk.models.webhook_mit_m_attack import WebhookMitMAttack class Webhook(BaseModel): @@ -97,7 +98,8 @@ class Webhook(BaseModel): 'suspect_score': 'WebhookSuspectScore', 'remote_control': 'WebhookRemoteControl', 'velocity': 'WebhookVelocity', - 'developer_tools': 'WebhookDeveloperTools' + 'developer_tools': 'WebhookDeveloperTools', + 'mitm_attack': 'WebhookMitMAttack' } nullable_map = { @@ -140,7 +142,8 @@ class Webhook(BaseModel): 'suspect_score': False, 'remote_control': False, 'velocity': False, - 'developer_tools': False + 'developer_tools': False, + 'mitm_attack': False } attribute_map = { @@ -183,10 +186,11 @@ class Webhook(BaseModel): 'suspect_score': 'suspectScore', 'remote_control': 'remoteControl', 'velocity': 'velocity', - 'developer_tools': 'developerTools' + 'developer_tools': 'developerTools', + 'mitm_attack': 'mitmAttack' } - def __init__(self, request_id=None, url=None, ip=None, tag=None, time=None, timestamp=None, ip_location=None, linked_id=None, visitor_id=None, visitor_found=None, confidence=None, first_seen_at=None, last_seen_at=None, browser_details=None, incognito=None, client_referrer=None, components=None, bot=None, user_agent=None, root_apps=None, emulator=None, ip_info=None, ip_blocklist=None, tor=None, vpn=None, proxy=None, tampering=None, cloned_app=None, factory_reset=None, jailbroken=None, frida=None, privacy_settings=None, virtual_machine=None, raw_device_attributes=None, high_activity=None, location_spoofing=None, suspect_score=None, remote_control=None, velocity=None, developer_tools=None): # noqa: E501 + def __init__(self, request_id=None, url=None, ip=None, tag=None, time=None, timestamp=None, ip_location=None, linked_id=None, visitor_id=None, visitor_found=None, confidence=None, first_seen_at=None, last_seen_at=None, browser_details=None, incognito=None, client_referrer=None, components=None, bot=None, user_agent=None, root_apps=None, emulator=None, ip_info=None, ip_blocklist=None, tor=None, vpn=None, proxy=None, tampering=None, cloned_app=None, factory_reset=None, jailbroken=None, frida=None, privacy_settings=None, virtual_machine=None, raw_device_attributes=None, high_activity=None, location_spoofing=None, suspect_score=None, remote_control=None, velocity=None, developer_tools=None, mitm_attack=None): # noqa: E501 """Webhook - a model defined in Swagger""" # noqa: E501 self._request_id = None self._url = None @@ -228,6 +232,7 @@ def __init__(self, request_id=None, url=None, ip=None, tag=None, time=None, time self._remote_control = None self._velocity = None self._developer_tools = None + self._mitm_attack = None self.discriminator = None self.request_id = request_id self.url = url @@ -304,6 +309,8 @@ def __init__(self, request_id=None, url=None, ip=None, tag=None, time=None, time self.velocity = velocity if developer_tools is not None: self.developer_tools = developer_tools + if mitm_attack is not None: + self.mitm_attack = mitm_attack @property def request_id(self) -> str: @@ -1093,3 +1100,22 @@ def developer_tools(self, developer_tools: Optional[WebhookDeveloperTools]): self._developer_tools = developer_tools + @property + def mitm_attack(self) -> Optional[WebhookMitMAttack]: + """Gets the mitm_attack of this Webhook. # noqa: E501 + + + :return: The mitm_attack of this Webhook. # noqa: E501 + """ + return self._mitm_attack + + @mitm_attack.setter + def mitm_attack(self, mitm_attack: Optional[WebhookMitMAttack]): + """Sets the mitm_attack of this Webhook. + + + :param mitm_attack: The mitm_attack of this Webhook. # noqa: E501 + """ + + self._mitm_attack = mitm_attack + diff --git a/fingerprint_pro_server_api_sdk/models/webhook_mit_m_attack.py b/fingerprint_pro_server_api_sdk/models/webhook_mit_m_attack.py new file mode 100644 index 00000000..5d107fa3 --- /dev/null +++ b/fingerprint_pro_server_api_sdk/models/webhook_mit_m_attack.py @@ -0,0 +1,69 @@ +# coding: utf-8 + +""" + Fingerprint Pro Server API + + Fingerprint Pro Server API allows you to get information about visitors and about individual events in a server environment. It can be used for data exports, decision-making, and data analysis scenarios. Server API is intended for server-side usage, it's not intended to be used from the client side, whether it's a browser or a mobile device. # noqa: E501 + + OpenAPI spec version: 3 + Contact: support@fingerprint.com + Generated by: https://github.com/swagger-api/swagger-codegen.git +""" + +import re # noqa: F401 +from typing import Dict, List, Optional # noqa: F401 +from fingerprint_pro_server_api_sdk.base_model import BaseModel + + +class WebhookMitMAttack(BaseModel): + """NOTE: This class is auto generated by the swagger code generator program. + + Do not edit the class manually. + """ + """ + Attributes: + swagger_types (dict): The key is attribute name + and the value is attribute type. + attribute_map (dict): The key is attribute name + and the value is json key in definition. + """ + swagger_types = { + 'result': 'bool' + } + + nullable_map = { + 'result': False + } + + attribute_map = { + 'result': 'result' + } + + def __init__(self, result=None): # noqa: E501 + """WebhookMitMAttack - a model defined in Swagger""" # noqa: E501 + self._result = None + self.discriminator = None + if result is not None: + self.result = result + + @property + def result(self) -> Optional[bool]: + """Gets the result of this WebhookMitMAttack. # noqa: E501 + + * `true` - When requests made from your users' mobile devices to Fingerprint servers have been intercepted and potentially modified. * `false` - Otherwise or when the request originated from a browser. See [MitM Attack Detection](https://dev.fingerprint.com/docs/smart-signals-overview#mitm-attack-detection) to learn more about this Smart Signal. # noqa: E501 + + :return: The result of this WebhookMitMAttack. # noqa: E501 + """ + return self._result + + @result.setter + def result(self, result: Optional[bool]): + """Sets the result of this WebhookMitMAttack. + + * `true` - When requests made from your users' mobile devices to Fingerprint servers have been intercepted and potentially modified. * `false` - Otherwise or when the request originated from a browser. See [MitM Attack Detection](https://dev.fingerprint.com/docs/smart-signals-overview#mitm-attack-detection) to learn more about this Smart Signal. # noqa: E501 + + :param result: The result of this WebhookMitMAttack. # noqa: E501 + """ + + self._result = result + diff --git a/res/fingerprint-server-api.yaml b/res/fingerprint-server-api.yaml index 75079ce6..9f957cf1 100644 --- a/res/fingerprint-server-api.yaml +++ b/res/fingerprint-server-api.yaml @@ -314,6 +314,7 @@ paths: how long you should wait before making a follow-up request. The value is non-negative decimal integer indicating the seconds to delay after the response is received. + x-flatten-optional-params: true parameters: - name: visitor_id in: path @@ -323,7 +324,7 @@ paths: description: >- Unique [visitor identifier](https://dev.fingerprint.com/reference/get-function#visitorid) - issued by Fingerprint Pro. + issued by Fingerprint Pro.\ - name: request_id in: query schema: @@ -338,6 +339,7 @@ paths: [result](https://dev.fingerprint.com/reference/get-function#requestid). When you filter visits by `requestId`, only one visit will be returned. + x-go-skip-pointer: true - name: linked_id in: query schema: @@ -352,6 +354,7 @@ paths: example: session ID, purchase ID, or transaction ID. You can then use this `linked_id` parameter to retrieve all events associated with your custom identifier. + x-go-skip-pointer: true - name: limit in: query schema: @@ -370,6 +373,7 @@ paths: By default, the most recent 100 visits are scanned, the maximum is 500. + x-go-skip-pointer: true - name: paginationKey in: query schema: @@ -398,6 +402,7 @@ paths: get less visits than the `limit` you specified with more available on the next page. When there are no more results available for scanning, the `paginationKey` attribute is not returned. + x-go-skip-pointer: true - name: before in: query deprecated: true @@ -408,6 +413,7 @@ paths: description: > ⚠️ Deprecated pagination method, please use `paginationKey` instead. Timestamp (in milliseconds since epoch) used to paginate results. + x-go-skip-pointer: true responses: '200': description: OK. @@ -640,6 +646,7 @@ paths: You can use HTTP basic authentication and set up credentials in your [Fingerprint account](https://dashboard.fingerprint.com/login) + x-flatten-optional-params: true requestBody: content: application/json: @@ -829,6 +836,8 @@ paths: 24h: 5 developerTools: result: false + mitmAttack: + result: false responses: default: description: The server doesn't validate the answer. @@ -1941,6 +1950,31 @@ components: $ref: '#/components/schemas/DeveloperTools' error: $ref: '#/components/schemas/Error' + MitMAttack: + type: object + additionalProperties: false + required: + - result + properties: + result: + type: boolean + description: > + * `true` - When requests made from your users' mobile devices to + Fingerprint servers have been intercepted and potentially modified. + + * `false` - Otherwise or when the request originated from a browser. + + See [MitM Attack + Detection](https://dev.fingerprint.com/docs/smart-signals-reference#mitm-attack-detection) + to learn more about this Smart Signal. + ProductMitMAttack: + type: object + additionalProperties: false + properties: + data: + $ref: '#/components/schemas/MitMAttack' + error: + $ref: '#/components/schemas/Error' Products: type: object description: >- @@ -1996,6 +2030,8 @@ components: $ref: '#/components/schemas/ProductVelocity' developerTools: $ref: '#/components/schemas/ProductDeveloperTools' + mitmAttack: + $ref: '#/components/schemas/ProductMitMAttack' EventsGetResponse: type: object description: >- @@ -2026,7 +2062,7 @@ components: suspect: type: boolean description: Suspect flag indicating observed suspicious or fraudulent event - x-go-skip-omitempty: true + x-go-force-pointer: true SearchEventsResponse: type: object description: >- @@ -2475,6 +2511,21 @@ components: description: > `true` if the browser is Chrome with DevTools open or Firefox with Developer Tools open, `false` otherwise. + WebhookMitMAttack: + type: object + additionalProperties: false + properties: + result: + type: boolean + description: > + * `true` - When requests made from your users' mobile devices to + Fingerprint servers have been intercepted and potentially modified. + + * `false` - Otherwise or when the request originated from a browser. + + See [MitM Attack + Detection](https://dev.fingerprint.com/docs/smart-signals-overview#mitm-attack-detection) + to learn more about this Smart Signal. Webhook: type: object required: @@ -2581,3 +2632,5 @@ components: $ref: '#/components/schemas/WebhookVelocity' developerTools: $ref: '#/components/schemas/WebhookDeveloperTools' + mitmAttack: + $ref: '#/components/schemas/WebhookMitMAttack' diff --git a/test/mocks/get_event_200.json b/test/mocks/get_event_200.json index 60013c0c..e88b5603 100644 --- a/test/mocks/get_event_200.json +++ b/test/mocks/get_event_200.json @@ -332,6 +332,11 @@ "data": { "result": false } + }, + "mitmAttack": { + "data": { + "result": false + } } } } diff --git a/test/mocks/get_event_200_all_errors.json b/test/mocks/get_event_200_all_errors.json index ddc55fac..e4876e19 100644 --- a/test/mocks/get_event_200_all_errors.json +++ b/test/mocks/get_event_200_all_errors.json @@ -153,6 +153,12 @@ "code": "Failed", "message": "internal server error" } + }, + "mitmAttack": { + "error": { + "code": "Failed", + "message": "internal server error" + } } } } diff --git a/test/mocks/get_event_200_with_broken_format.json b/test/mocks/get_event_200_with_broken_format.json index 4ac8b6f5..1c4a2119 100644 --- a/test/mocks/get_event_200_with_broken_format.json +++ b/test/mocks/get_event_200_with_broken_format.json @@ -278,6 +278,11 @@ "data": { "result": false } + }, + "mitmAttack": { + "data": { + "result": false + } } } } diff --git a/test/mocks/get_event_200_with_unknown_field.json b/test/mocks/get_event_200_with_unknown_field.json index eba63e09..39111b39 100644 --- a/test/mocks/get_event_200_with_unknown_field.json +++ b/test/mocks/get_event_200_with_unknown_field.json @@ -280,6 +280,11 @@ "data": { "result": false } + }, + "mitmAttack": { + "data": { + "result": false + } } } } diff --git a/test/mocks/get_event_search_200.json b/test/mocks/get_event_search_200.json index 9d237eb6..b90f62c9 100644 --- a/test/mocks/get_event_search_200.json +++ b/test/mocks/get_event_search_200.json @@ -334,6 +334,11 @@ "data": { "result": false } + }, + "mitmAttack": { + "data": { + "result": false + } } }} ], diff --git a/test/mocks/webhook.json b/test/mocks/webhook.json index 748d2529..24c5b528 100644 --- a/test/mocks/webhook.json +++ b/test/mocks/webhook.json @@ -242,5 +242,8 @@ }, "developerTools": { "result": false + }, + "mitmAttack": { + "result": false } } From 774449827761010d6d63e88fd0b28768293c4b31 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Przemys=C5=82aw=20=C5=BBydek?= Date: Fri, 28 Mar 2025 10:52:57 +0100 Subject: [PATCH 2/3] fix: remove "\" schema typo --- docs/FingerprintApi.md | 4 ++-- fingerprint_pro_server_api_sdk/api/fingerprint_api.py | 4 ++-- res/fingerprint-server-api.yaml | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/FingerprintApi.md b/docs/FingerprintApi.md index ba90afa9..a15ac001 100644 --- a/docs/FingerprintApi.md +++ b/docs/FingerprintApi.md @@ -179,7 +179,7 @@ configuration = fingerprint_pro_server_api_sdk.Configuration(api_key="SECRET_API # create an instance of the API class api_instance = fingerprint_pro_server_api_sdk.FingerprintApi(configuration) -visitor_id = 'visitor_id_example' # str | Unique [visitor identifier](https://dev.fingerprint.com/reference/get-function#visitorid) issued by Fingerprint Pro.\\ +visitor_id = 'visitor_id_example' # str | Unique [visitor identifier](https://dev.fingerprint.com/reference/get-function#visitorid) issued by Fingerprint Pro. request_id = 'request_id_example' # str | Filter visits by `requestId`. Every identification request has a unique identifier associated with it called `requestId`. This identifier is returned to the client in the identification [result](https://dev.fingerprint.com/reference/get-function#requestid). When you filter visits by `requestId`, only one visit will be returned. (optional) linked_id = 'linked_id_example' # str | Filter visits by your custom identifier. You can use [`linkedId`](https://dev.fingerprint.com/reference/get-function#linkedid) to associate identification requests with your own identifier, for example: session ID, purchase ID, or transaction ID. You can then use this `linked_id` parameter to retrieve all events associated with your custom identifier. (optional) limit = 56 # int | Limit scanned results. For performance reasons, the API first scans some number of events before filtering them. Use `limit` to specify how many events are scanned before they are filtered by `requestId` or `linkedId`. Results are always returned sorted by the timestamp (most recent first). By default, the most recent 100 visits are scanned, the maximum is 500. (optional) @@ -198,7 +198,7 @@ except ApiException as e: Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- - **visitor_id** | **str**| Unique [visitor identifier](https://dev.fingerprint.com/reference/get-function#visitorid) issued by Fingerprint Pro.\\ | + **visitor_id** | **str**| Unique [visitor identifier](https://dev.fingerprint.com/reference/get-function#visitorid) issued by Fingerprint Pro. | **request_id** | **str**| Filter visits by `requestId`. Every identification request has a unique identifier associated with it called `requestId`. This identifier is returned to the client in the identification [result](https://dev.fingerprint.com/reference/get-function#requestid). When you filter visits by `requestId`, only one visit will be returned. | [optional] **linked_id** | **str**| Filter visits by your custom identifier. You can use [`linkedId`](https://dev.fingerprint.com/reference/get-function#linkedid) to associate identification requests with your own identifier, for example: session ID, purchase ID, or transaction ID. You can then use this `linked_id` parameter to retrieve all events associated with your custom identifier. | [optional] **limit** | **int**| Limit scanned results. For performance reasons, the API first scans some number of events before filtering them. Use `limit` to specify how many events are scanned before they are filtered by `requestId` or `linkedId`. Results are always returned sorted by the timestamp (most recent first). By default, the most recent 100 visits are scanned, the maximum is 500. | [optional] diff --git a/fingerprint_pro_server_api_sdk/api/fingerprint_api.py b/fingerprint_pro_server_api_sdk/api/fingerprint_api.py index be08ebbc..a69e3b5d 100644 --- a/fingerprint_pro_server_api_sdk/api/fingerprint_api.py +++ b/fingerprint_pro_server_api_sdk/api/fingerprint_api.py @@ -374,7 +374,7 @@ def get_visits(self, visitor_id: str, **kwargs) -> Union[VisitorsGetResponse, As >>> result = thread.get() :param async_req bool - :param visitor_id: Unique [visitor identifier](https://dev.fingerprint.com/reference/get-function#visitorid) issued by Fingerprint Pro.\\ (required) + :param visitor_id: Unique [visitor identifier](https://dev.fingerprint.com/reference/get-function#visitorid) issued by Fingerprint Pro. (required) :param request_id: Filter visits by `requestId`. Every identification request has a unique identifier associated with it called `requestId`. This identifier is returned to the client in the identification [result](https://dev.fingerprint.com/reference/get-function#requestid). When you filter visits by `requestId`, only one visit will be returned. :param linked_id: Filter visits by your custom identifier. You can use [`linkedId`](https://dev.fingerprint.com/reference/get-function#linkedid) to associate identification requests with your own identifier, for example: session ID, purchase ID, or transaction ID. You can then use this `linked_id` parameter to retrieve all events associated with your custom identifier. :param limit: Limit scanned results. For performance reasons, the API first scans some number of events before filtering them. Use `limit` to specify how many events are scanned before they are filtered by `requestId` or `linkedId`. Results are always returned sorted by the timestamp (most recent first). By default, the most recent 100 visits are scanned, the maximum is 500. @@ -401,7 +401,7 @@ def get_visits_with_http_info(self, visitor_id: str, **kwargs): # noqa: E501 >>> result = thread.get() :param async_req bool - :param str visitor_id: Unique [visitor identifier](https://dev.fingerprint.com/reference/get-function#visitorid) issued by Fingerprint Pro.\\ (required) + :param str visitor_id: Unique [visitor identifier](https://dev.fingerprint.com/reference/get-function#visitorid) issued by Fingerprint Pro. (required) :param str request_id: Filter visits by `requestId`. Every identification request has a unique identifier associated with it called `requestId`. This identifier is returned to the client in the identification [result](https://dev.fingerprint.com/reference/get-function#requestid). When you filter visits by `requestId`, only one visit will be returned. :param str linked_id: Filter visits by your custom identifier. You can use [`linkedId`](https://dev.fingerprint.com/reference/get-function#linkedid) to associate identification requests with your own identifier, for example: session ID, purchase ID, or transaction ID. You can then use this `linked_id` parameter to retrieve all events associated with your custom identifier. :param int limit: Limit scanned results. For performance reasons, the API first scans some number of events before filtering them. Use `limit` to specify how many events are scanned before they are filtered by `requestId` or `linkedId`. Results are always returned sorted by the timestamp (most recent first). By default, the most recent 100 visits are scanned, the maximum is 500. diff --git a/res/fingerprint-server-api.yaml b/res/fingerprint-server-api.yaml index 9f957cf1..301dd653 100644 --- a/res/fingerprint-server-api.yaml +++ b/res/fingerprint-server-api.yaml @@ -324,7 +324,7 @@ paths: description: >- Unique [visitor identifier](https://dev.fingerprint.com/reference/get-function#visitorid) - issued by Fingerprint Pro.\ + issued by Fingerprint Pro. - name: request_id in: query schema: From 2ce769e58509fea50970f29809003a9ce81321e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Przemys=C5=82aw=20=C5=BBydek?= Date: Tue, 1 Apr 2025 14:58:16 +0200 Subject: [PATCH 3/3] chore: use correct package name in the changeset --- .changeset/add-mitmattack-smartsignal.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changeset/add-mitmattack-smartsignal.md b/.changeset/add-mitmattack-smartsignal.md index 37d28f8c..8a7a5da1 100644 --- a/.changeset/add-mitmattack-smartsignal.md +++ b/.changeset/add-mitmattack-smartsignal.md @@ -1,5 +1,5 @@ --- -"fingerprint-pro-server-api-openapi": minor +"fingerprint-pro-server-api-python-sdk'": minor --- Add `mitmAttack` (man-in-the-middle attack) Smart Signal.