From d847128d19dc18320750ed3505af94176afbe601 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Przemys=C5=82aw=20=C5=BBydek?= Date: Thu, 13 Jul 2023 13:38:24 +0200 Subject: [PATCH] feat: add smart signals support --- resources/fingerprint-server-api.yaml | 252 ++++++++++++++++-- src/generatedApiTypes.ts | 164 +++++++++++- .../castVisitorWebhookTest.spec.ts.snap | 19 ++ .../__snapshots__/getEventTests.spec.ts.snap | 31 +++ .../external/get_event.json | 31 +++ .../external/webhook.json | 19 ++ 6 files changed, 482 insertions(+), 34 deletions(-) diff --git a/resources/fingerprint-server-api.yaml b/resources/fingerprint-server-api.yaml index 7ece24c..d0162e5 100644 --- a/resources/fingerprint-server-api.yaml +++ b/resources/fingerprint-server-api.yaml @@ -47,13 +47,15 @@ paths: operationId: getEvent summary: Get event by requestId description: > - This endpoint allows you to retrieve an individual analysis event with - all the information from each activated product (Identification, Bot - Detection, and others). + This endpoint allows you to get a detailed analysis of an individual + request. - Products that are not activated for your application or not relevant to - the event's detected platform (web, iOS, Android) are not included in - the response. + **Only for Enterprise customers:** Please note that the response + includes mobile signals (e.g. `rootApps`) even if the request orignated + from a non-mobile platform. + + It is highly recommended that you **ignore** the mobile signals for such + requests. Use `requestId` as the URL path parameter. This API method is scoped to @@ -184,6 +186,25 @@ paths: data: result: false anomalyScore: 0 + 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 allErrorsResponse: summary: All failed signals value: @@ -3630,6 +3651,19 @@ paths: tampering: result: false anomalyScore: 0 + clonedApp: + result: false + factoryReset: + time: '1970-01-01T00:00:00Z' + timestamp: 0 + jailbroken: + result: false + frida: + result: false + privacySettings: + result: false + virtualMachine: + result: false responses: default: description: The server doesn't validate the answer. @@ -3847,10 +3881,8 @@ components: description: > Android specific root management apps detection. There are 2 values: • `true` - Root Management Apps detected (e.g. Magisk) • - `false` - No Root Management Apps detected - - Available only for events from Android client. The field will - not be present for a browser or iOS event. + `false` - No Root Management Apps detected or the client isn't + Android. example: false emulator: title: WebhookSignalResponseEmulator @@ -3861,10 +3893,63 @@ components: description: > Android specific emulator detection. There are 2 values: • `true` - Emulated environment detected (e.g. launch inside of - AVD) • `false` - No signs of emulated environment detected - - Available only for events from Android client. The field will - not be present for a browser or iOS event. + AVD) • `false` - No signs of emulated environment detected or + the client isn't Android. + example: false + clonedApp: + title: WebhookSignalResponseClonedApp + type: object + properties: + result: + type: boolean + description: > + Android specific cloned application detection. There are 2 + values: • `true` - Presence of app cloners work detected (e.g. + fully cloned application found or launch of it inside of a not + main working profile detected). • `false` - No signs of cloned + application detected or the client is not Android. + example: false + factoryReset: + title: WebhookSignalResponseFactoryReset + type: object + properties: + time: + title: Time + description: > + Time in UTC for the Android client when recent factory reset was + done. If there is no sign of factory reset or the client isn't + Android, the field will be epoch time. + type: string + format: date-time + example: '2022-06-09T22:58:36Z' + timestamp: + description: >- + Same value as it's in the `time` field but represented in + timestamp format. + type: integer + format: int64 + example: 1654815517198 + jailbroken: + title: WebhookSignalResponseJailbroken + type: object + properties: + result: + type: boolean + description: > + iOS specific jailbreak detection. There are 2 values: • `true` - + Jailbreak detected • `false` - No signs of jailbreak or the + client is not iOS. + example: false + frida: + title: WebhookSignalResponseFrida + type: object + properties: + result: + type: boolean + description: > + iOS specific [Frida](https://frida.re/docs/ios/) detection. + There are 2 values: • `true` - Frida detected • `false` - No + signs of Frida or the client is not iOS. example: false ipBlocklist: $ref: '#/components/schemas/IpBlockListResult' @@ -3878,6 +3963,27 @@ components: `true` if the request IP address is a known tor exit node, `false` otherwise. example: false + privacySettings: + title: WebhookSignalResponsePrivacySettings + type: object + properties: + result: + type: boolean + description: > + `true` if the request is from a privacy aware browser (e.g. Tor) + or from a browser in which fingerprinting is blocked. Otherwise + `false`. + example: false + virtualMachine: + title: WebhookSignalResponseVirtualMachine + type: object + properties: + result: + type: boolean + description: > + `true` if the request came from a browser running inside a + virtual machine (e.g. VMWare), `false` otherwise. + example: false vpn: $ref: '#/components/schemas/VpnResult' proxy: @@ -4297,10 +4403,8 @@ components: description: > Android specific root management apps detection. There are 2 values: • `true` - Root Management Apps detected (e.g. - Magisk) • `false` - No Root Management Apps detected - - Available only for events from Android client. The field - will not be present for a browser or iOS event. + Magisk) • `false` - No Root Management Apps detected or the + client is not Android. example: false error: $ref: '#/components/schemas/ProductError' @@ -4317,10 +4421,83 @@ components: Android specific emulator detection. There are 2 values: • `true` - Emulated environment detected (e.g. launch inside of AVD) • `false` - No signs of emulated environment - detected - - Available only for events from Android client. The field - will not be present for a browser or iOS event. + detected or the client is not Android. + example: false + error: + $ref: '#/components/schemas/ProductError' + clonedApp: + title: SignalResponseClonedApp + type: object + properties: + data: + type: object + properties: + result: + type: boolean + description: > + Android specific cloned application detection. There are 2 + values: • `true` - Presence of app cloners work detected + (e.g. fully cloned application found or launch of it inside + of a not main working profile detected). • `false` - No + signs of cloned application detected or the client is not + Android. + example: false + error: + $ref: '#/components/schemas/ProductError' + factoryReset: + title: SignalResponseFactoryReset + type: object + properties: + data: + type: object + properties: + time: + title: Time + description: > + Time in UTC for the Android client when recent factory reset + was done. If there is no sign of factory reset or the + client isn't Android, the field will be epoch time. + type: string + format: date-time + example: '2022-06-09T22:58:36Z' + timestamp: + description: >- + Same value as it's in the `time` field but represented in + timestamp format. + type: integer + format: int64 + example: 1654815517198 + error: + $ref: '#/components/schemas/ProductError' + jailbroken: + title: SignalResponseJailbroken + type: object + properties: + data: + type: object + properties: + result: + type: boolean + description: > + iOS specific jailbreak detection. There are 2 values: • + `true` - Jailbreak detected • `false` - No signs of + jailbreak or the client is not iOS. + example: false + error: + $ref: '#/components/schemas/ProductError' + frida: + title: SignalResponseFrida + type: object + properties: + data: + type: object + properties: + result: + type: boolean + description: > + iOS specific [Frida](https://frida.re/docs/ios/) detection. + There are 2 values: • `true` - Frida detected • `false` - No + signs of Frida or the client is not iOS. example: false error: $ref: '#/components/schemas/ProductError' @@ -4347,6 +4524,37 @@ components: example: false error: $ref: '#/components/schemas/ProductError' + privacySettings: + title: SignalResponsePrivacySettings + type: object + properties: + data: + type: object + properties: + result: + type: boolean + description: > + `true` if the request is from a privacy aware browser (e.g. + Tor) or from a browser in which fingerprinting is blocked. + Otherwise `false`. + example: false + error: + $ref: '#/components/schemas/ProductError' + virtualMachine: + title: SignalResponseVirtualMachine + type: object + properties: + data: + type: object + properties: + result: + type: boolean + description: > + `true` if the request came from a browser running inside a + virtual machine (e.g. VMWare), `false` otherwise. + example: false + error: + $ref: '#/components/schemas/ProductError' vpn: title: SignalResponseVpn type: object diff --git a/src/generatedApiTypes.ts b/src/generatedApiTypes.ts index 04a22aa..102926d 100644 --- a/src/generatedApiTypes.ts +++ b/src/generatedApiTypes.ts @@ -6,8 +6,9 @@ export interface paths { '/events/{request_id}': { /** - * This endpoint allows you to retrieve an individual analysis event with all the information from each activated product (Identification, Bot Detection, and others). - * Products that are not activated for your application or not relevant to the event's detected platform (web, iOS, Android) are not included in the response. + * This endpoint allows you to get a detailed analysis of an individual request. + * **Only for Enterprise customers:** Please note that the response includes mobile signals (e.g. `rootApps`) even if the request orignated from a non-mobile platform. + * It is highly recommended that you **ignore** the mobile signals for such requests. * * Use `requestId` as the URL path parameter. This API method is scoped to a request, i.e. all returned information is by `requestId`. */ @@ -164,8 +165,7 @@ export interface components { /** WebhookSignalResponseRootApps */ rootApps?: { /** - * @description Android specific root management apps detection. There are 2 values: • `true` - Root Management Apps detected (e.g. Magisk) • `false` - No Root Management Apps detected - * Available only for events from Android client. The field will not be present for a browser or iOS event. + * @description Android specific root management apps detection. There are 2 values: • `true` - Root Management Apps detected (e.g. Magisk) • `false` - No Root Management Apps detected or the client isn't Android. * * @example false */ @@ -174,8 +174,51 @@ export interface components { /** WebhookSignalResponseEmulator */ emulator?: { /** - * @description Android specific emulator detection. There are 2 values: • `true` - Emulated environment detected (e.g. launch inside of AVD) • `false` - No signs of emulated environment detected - * Available only for events from Android client. The field will not be present for a browser or iOS event. + * @description Android specific emulator detection. There are 2 values: • `true` - Emulated environment detected (e.g. launch inside of AVD) • `false` - No signs of emulated environment detected or the client isn't Android. + * + * @example false + */ + result?: boolean; + }; + /** WebhookSignalResponseClonedApp */ + clonedApp?: { + /** + * @description Android specific cloned application detection. There are 2 values: • `true` - Presence of app cloners work detected (e.g. fully cloned application found or launch of it inside of a not main working profile detected). • `false` - No signs of cloned application detected or the client is not Android. + * + * @example false + */ + result?: boolean; + }; + /** WebhookSignalResponseFactoryReset */ + factoryReset?: { + /** + * Time + * Format: date-time + * @description Time in UTC for the Android client when recent factory reset was done. If there is no sign of factory reset or the client isn't Android, the field will be epoch time. + * + * @example 2022-06-09T22:58:36Z + */ + time?: string; + /** + * Format: int64 + * @description Same value as it's in the `time` field but represented in timestamp format. + * @example 1654815517198 + */ + timestamp?: number; + }; + /** WebhookSignalResponseJailbroken */ + jailbroken?: { + /** + * @description iOS specific jailbreak detection. There are 2 values: • `true` - Jailbreak detected • `false` - No signs of jailbreak or the client is not iOS. + * + * @example false + */ + result?: boolean; + }; + /** WebhookSignalResponseFrida */ + frida?: { + /** + * @description iOS specific [Frida](https://frida.re/docs/ios/) detection. There are 2 values: • `true` - Frida detected • `false` - No signs of Frida or the client is not iOS. * * @example false */ @@ -191,6 +234,24 @@ export interface components { */ result?: boolean; }; + /** WebhookSignalResponsePrivacySettings */ + privacySettings?: { + /** + * @description `true` if the request is from a privacy aware browser (e.g. Tor) or from a browser in which fingerprinting is blocked. Otherwise `false`. + * + * @example false + */ + result?: boolean; + }; + /** WebhookSignalResponseVirtualMachine */ + virtualMachine?: { + /** + * @description `true` if the request came from a browser running inside a virtual machine (e.g. VMWare), `false` otherwise. + * + * @example false + */ + result?: boolean; + }; vpn?: components['schemas']['VpnResult']; /** WebhookSignalResponseProxy */ proxy?: { @@ -463,8 +524,7 @@ export interface components { rootApps?: { data?: { /** - * @description Android specific root management apps detection. There are 2 values: • `true` - Root Management Apps detected (e.g. Magisk) • `false` - No Root Management Apps detected - * Available only for events from Android client. The field will not be present for a browser or iOS event. + * @description Android specific root management apps detection. There are 2 values: • `true` - Root Management Apps detected (e.g. Magisk) • `false` - No Root Management Apps detected or the client is not Android. * * @example false */ @@ -476,8 +536,63 @@ export interface components { emulator?: { data?: { /** - * @description Android specific emulator detection. There are 2 values: • `true` - Emulated environment detected (e.g. launch inside of AVD) • `false` - No signs of emulated environment detected - * Available only for events from Android client. The field will not be present for a browser or iOS event. + * @description Android specific emulator detection. There are 2 values: • `true` - Emulated environment detected (e.g. launch inside of AVD) • `false` - No signs of emulated environment detected or the client is not Android. + * + * @example false + */ + result?: boolean; + }; + error?: components['schemas']['ProductError']; + }; + /** SignalResponseClonedApp */ + clonedApp?: { + data?: { + /** + * @description Android specific cloned application detection. There are 2 values: • `true` - Presence of app cloners work detected (e.g. fully cloned application found or launch of it inside of a not main working profile detected). • `false` - No signs of cloned application detected or the client is not Android. + * + * @example false + */ + result?: boolean; + }; + error?: components['schemas']['ProductError']; + }; + /** SignalResponseFactoryReset */ + factoryReset?: { + data?: { + /** + * Time + * Format: date-time + * @description Time in UTC for the Android client when recent factory reset was done. If there is no sign of factory reset or the client isn't Android, the field will be epoch time. + * + * @example 2022-06-09T22:58:36Z + */ + time?: string; + /** + * Format: int64 + * @description Same value as it's in the `time` field but represented in timestamp format. + * @example 1654815517198 + */ + timestamp?: number; + }; + error?: components['schemas']['ProductError']; + }; + /** SignalResponseJailbroken */ + jailbroken?: { + data?: { + /** + * @description iOS specific jailbreak detection. There are 2 values: • `true` - Jailbreak detected • `false` - No signs of jailbreak or the client is not iOS. + * + * @example false + */ + result?: boolean; + }; + error?: components['schemas']['ProductError']; + }; + /** SignalResponseFrida */ + frida?: { + data?: { + /** + * @description iOS specific [Frida](https://frida.re/docs/ios/) detection. There are 2 values: • `true` - Frida detected • `false` - No signs of Frida or the client is not iOS. * * @example false */ @@ -502,6 +617,30 @@ export interface components { }; error?: components['schemas']['ProductError']; }; + /** SignalResponsePrivacySettings */ + privacySettings?: { + data?: { + /** + * @description `true` if the request is from a privacy aware browser (e.g. Tor) or from a browser in which fingerprinting is blocked. Otherwise `false`. + * + * @example false + */ + result?: boolean; + }; + error?: components['schemas']['ProductError']; + }; + /** SignalResponseVirtualMachine */ + virtualMachine?: { + data?: { + /** + * @description `true` if the request came from a browser running inside a virtual machine (e.g. VMWare), `false` otherwise. + * + * @example false + */ + result?: boolean; + }; + error?: components['schemas']['ProductError']; + }; /** SignalResponseVpn */ vpn?: { data?: components['schemas']['VpnResult']; @@ -672,8 +811,9 @@ export interface components { export interface operations { /** - * This endpoint allows you to retrieve an individual analysis event with all the information from each activated product (Identification, Bot Detection, and others). - * Products that are not activated for your application or not relevant to the event's detected platform (web, iOS, Android) are not included in the response. + * This endpoint allows you to get a detailed analysis of an individual request. + * **Only for Enterprise customers:** Please note that the response includes mobile signals (e.g. `rootApps`) even if the request orignated from a non-mobile platform. + * It is highly recommended that you **ignore** the mobile signals for such requests. * * Use `requestId` as the URL path parameter. This API method is scoped to a request, i.e. all returned information is by `requestId`. */ diff --git a/tests/mocked-responses-tests/__snapshots__/castVisitorWebhookTest.spec.ts.snap b/tests/mocked-responses-tests/__snapshots__/castVisitorWebhookTest.spec.ts.snap index f487d51..a64f872 100644 --- a/tests/mocked-responses-tests/__snapshots__/castVisitorWebhookTest.spec.ts.snap +++ b/tests/mocked-responses-tests/__snapshots__/castVisitorWebhookTest.spec.ts.snap @@ -16,16 +16,26 @@ Object { "userAgent": "(Macintosh; Intel Mac OS X 10_14_3) Chrome/73.0.3683.86", }, "clientReferrer": "https://google.com?search=banking+services", + "clonedApp": Object { + "result": false, + }, "confidence": Object { "score": 0.97, }, "emulator": Object { "result": false, }, + "factoryReset": Object { + "time": "1970-01-01T00:00:00Z", + "timestamp": 0, + }, "firstSeenAt": Object { "global": "2022-03-16T11:26:45.362Z", "subscription": "2022-03-16T11:31:01.101Z", }, + "frida": Object { + "result": false, + }, "incognito": false, "ip": "216.3.128.12", "ipBlocklist": Object { @@ -88,11 +98,17 @@ Object { ], "timezone": "America/Chicago", }, + "jailbroken": Object { + "result": false, + }, "lastSeenAt": Object { "global": "2022-03-16T11:28:34.023Z", "subscription": null, }, "linkedId": "any-string", + "privacySettings": Object { + "result": false, + }, "proxy": Object { "result": false, }, @@ -115,6 +131,9 @@ Object { }, "url": "https://banking.example.com/signup", "userAgent": "(Macintosh; Intel Mac OS X 10_14_3) Chrome/73.0.3683.86", + "virtualMachine": Object { + "result": false, + }, "visitorFound": true, "visitorId": "3HNey93AkBW6CRbxV6xP", "vpn": Object { diff --git a/tests/mocked-responses-tests/__snapshots__/getEventTests.spec.ts.snap b/tests/mocked-responses-tests/__snapshots__/getEventTests.spec.ts.snap index 9207196..643c84f 100644 --- a/tests/mocked-responses-tests/__snapshots__/getEventTests.spec.ts.snap +++ b/tests/mocked-responses-tests/__snapshots__/getEventTests.spec.ts.snap @@ -183,11 +183,27 @@ Object { "url": "https://www.example.com/login", }, }, + "clonedApp": Object { + "data": Object { + "result": false, + }, + }, "emulator": Object { "data": Object { "result": false, }, }, + "factoryReset": Object { + "data": Object { + "time": "1970-01-01T00:00:00Z", + "timestamp": 0, + }, + }, + "frida": Object { + "data": Object { + "result": false, + }, + }, "identification": Object { "data": Object { "browserDetails": Object { @@ -290,6 +306,16 @@ Object { }, }, }, + "jailbroken": Object { + "data": Object { + "result": false, + }, + }, + "privacySettings": Object { + "data": Object { + "result": false, + }, + }, "proxy": Object { "data": Object { "result": false, @@ -311,6 +337,11 @@ Object { "result": false, }, }, + "virtualMachine": Object { + "data": Object { + "result": false, + }, + }, "vpn": Object { "data": Object { "methods": Object { diff --git a/tests/mocked-responses-tests/mocked-responses-data/external/get_event.json b/tests/mocked-responses-tests/mocked-responses-data/external/get_event.json index 924545c..83f2ae1 100644 --- a/tests/mocked-responses-tests/mocked-responses-data/external/get_event.json +++ b/tests/mocked-responses-tests/mocked-responses-data/external/get_event.json @@ -147,6 +147,37 @@ "result": false, "anomalyScore": 0 } + }, + "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 + } } } } diff --git a/tests/mocked-responses-tests/mocked-responses-data/external/webhook.json b/tests/mocked-responses-tests/mocked-responses-data/external/webhook.json index e5103a1..aca7ee0 100644 --- a/tests/mocked-responses-tests/mocked-responses-data/external/webhook.json +++ b/tests/mocked-responses-tests/mocked-responses-data/external/webhook.json @@ -120,5 +120,24 @@ "tampering": { "result": false, "anomalyScore": 0 + }, + "clonedApp": { + "result": false + }, + "factoryReset": { + "time": "1970-01-01T00:00:00Z", + "timestamp": 0 + }, + "jailbroken": { + "result": false + }, + "frida": { + "result": false + }, + "privacySettings": { + "result": false + }, + "virtualMachine": { + "result": false } }