diff --git a/.changeset/config.json b/.changeset/config.json
index b3e38b7c..09d18e8f 100644
--- a/.changeset/config.json
+++ b/.changeset/config.json
@@ -4,9 +4,15 @@
"@fingerprintjs/changesets-native-dependency-format",
{
"repo": "fingerprintjs/react-native",
- "androidPath": "sdk/android",
- "iosPodspecPath": "sdk/RNFingerprint.podspec",
- "packageName": "@fingerprint/react-native"
+ "packageName": "@fingerprint/react-native",
+ "ios": {
+ "podspecPath": "sdk/RNFingerprint.podspec",
+ "dependencyName": "Fingerprint-iOS"
+ },
+ "android": {
+ "path": "sdk/android",
+ "gradleTaskName": "printFingerprintNativeSDKVersion"
+ }
}
],
"commit": false,
diff --git a/.changeset/pre.json b/.changeset/pre.json
index 0bfe8cfb..1881f128 100644
--- a/.changeset/pre.json
+++ b/.changeset/pre.json
@@ -1,5 +1,5 @@
{
- "mode": "pre",
+ "mode": "exit",
"tag": "rc",
"initialVersions": {
"@fingerprint/react-native": "3.17.0"
diff --git a/.github/workflows/docs-and-coverage.yml b/.github/workflows/docs-and-coverage.yml
index 205bca0b..5fef1cae 100644
--- a/.github/workflows/docs-and-coverage.yml
+++ b/.github/workflows/docs-and-coverage.yml
@@ -9,7 +9,7 @@ jobs:
generate-docs-and-coverage:
name: Generate docs and coverage report
uses: fingerprintjs/dx-team-toolkit/.github/workflows/docs-and-coverage.yml@v1
- with:
- prepare-gh-pages-commands: |
- mv docs/* ./gh-pages
- mv coverage/lcov-report ./gh-pages/coverage
+ permissions:
+ contents: read
+ pages: write
+ id-token: write
diff --git a/.github/workflows/e2e-tests.yml b/.github/workflows/e2e-tests.yml
index 7d36e079..0f4f952d 100644
--- a/.github/workflows/e2e-tests.yml
+++ b/.github/workflows/e2e-tests.yml
@@ -59,7 +59,7 @@ jobs:
REACT_NATIVE_VERSION: ${{ matrix.react-native }}
- name: Install ${{github.event.release.tag_name}} version of the package
- run: pnpm add @fingerprint/react-native@${{github.event.release.tag_name}}
+ run: pnpm add ${{github.event.release.tag_name}}
if: github.event_name == 'release'
working-directory: e2e-app
@@ -259,7 +259,7 @@ jobs:
REACT_NATIVE_VERSION: ${{ matrix.react-native }}
- name: Install ${{github.event.release.tag_name}} version of the package
- run: pnpm add @fingerprint/react-native@${{github.event.release.tag_name}}
+ run: pnpm add ${{github.event.release.tag_name}}
if: github.event_name == 'release'
working-directory: e2e-app
@@ -410,7 +410,7 @@ jobs:
working-directory: e2e-app
- name: Install ${{github.event.release.tag_name}} version of the package
- run: pnpm add @fingerprint/react-native@${{github.event.release.tag_name}}
+ run: pnpm add ${{github.event.release.tag_name}}
if: github.event_name == 'release'
working-directory: e2e-app
diff --git a/README.md b/README.md
index 9077bc86..f902a8bc 100644
--- a/README.md
+++ b/README.md
@@ -363,6 +363,26 @@ return (
)
```
+### Custom endpoints
+
+To avoid ad blockers, proxy identification through a [proxy integration](https://docs.fingerprint.com/docs/protecting-the-javascript-agent-from-adblockers). Pass identification URLs as `endpoints`, first to last.
+
+We recommend including the default API URL for your [region](https://docs.fingerprint.com/docs/regions) as a fallback: `https://api.fpjs.io` (US), `https://eu.api.fpjs.io` (EU), `https://ap.api.fpjs.io` (Asia). There are no fallbacks by default.
+
+
+```javascript
+return (
+
+
+
+)
+```
+
## API Reference
See the full [generated API Reference](https://fingerprintjs.github.io/react-native/).
diff --git a/package.json b/package.json
index 4c99dc37..1f7d977b 100644
--- a/package.json
+++ b/package.json
@@ -36,7 +36,7 @@
"@changesets/types": "^6.1.0",
"@commitlint/cli": "^21.2.1",
"@eslint-react/eslint-plugin": "^5.16.1",
- "@fingerprintjs/changesets-native-dependency-format": "^0.1.0",
+ "@fingerprintjs/changesets-native-dependency-format": "^0.2.0",
"@fingerprintjs/commit-lint-dx-team": "^0.1.0",
"@fingerprintjs/eslint-config-dx-team": "^3.0.0",
"@fingerprintjs/prettier-config-dx-team": "^0.3.0",
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index abf617d8..c7f5f517 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -24,8 +24,8 @@ importers:
specifier: ^5.16.1
version: 5.16.1(eslint@10.7.0(jiti@2.6.1))(typescript@6.0.3)
'@fingerprintjs/changesets-native-dependency-format':
- specifier: ^0.1.0
- version: 0.1.0
+ specifier: ^0.2.0
+ version: 0.2.0
'@fingerprintjs/commit-lint-dx-team':
specifier: ^0.1.0
version: 0.1.0
@@ -1306,8 +1306,8 @@ packages:
'@fingerprintjs/changesets-changelog-format@0.2.0':
resolution: {integrity: sha512-1jI+J1r8OKUtjlFfQW4bmQ8u4E1097zPaKw5fUCgAcahLPgwW4Ae+Keoc253CSyyaKgTu2v/wniUGchmPaXAsg==}
- '@fingerprintjs/changesets-native-dependency-format@0.1.0':
- resolution: {integrity: sha512-fRrunw8LFXjKEFGWxSB/LG1/0GRkZARKNEs1Zuz9rOSDsJdjzhsYnv1Bo0IEkv7tTCTTJk69oAXGYFOXtWfHeg==}
+ '@fingerprintjs/changesets-native-dependency-format@0.2.0':
+ resolution: {integrity: sha512-wUh8Zg+veIPyLs8YWl1AOb1ARUy0F+Yw2ak1Cr0n2U3QCXlZPZ7lTt24DmKSoOgqbA4ZQqu2DOupgsNajkgOog==}
'@fingerprintjs/commit-lint-dx-team@0.1.0':
resolution: {integrity: sha512-MSYn4bRt9Iyob8hB3Oc/IXz3O8DA2E3ccqlG46pYYhdF090W6u9BNa9uCaVg611FUzqMU41+vs8ztXLkICbKkw==}
@@ -2071,10 +2071,12 @@ packages:
'@xmldom/xmldom@0.8.13':
resolution: {integrity: sha512-KRYzxepc14G/CEpEGc3Yn+JKaAeT63smlDr+vjB8jRfgTBBI9wRj/nkQEO+ucV8p8I9bfKLWp37uHgFrbntPvw==}
engines: {node: '>=10.0.0'}
+ deprecated: this version has critical issues, please update to the latest version
'@xmldom/xmldom@0.9.10':
resolution: {integrity: sha512-A9gOqLdi6cV4ibazAjcQufGj0B1y/vDqYrcuP6d/6x8P27gRS8643Dj9o1dEKtB6O7fwxb2FgBmJS2mX7gpvdw==}
engines: {node: '>=14.6'}
+ deprecated: this version has critical issues, please update to the latest version
abab@2.0.6:
resolution: {integrity: sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA==}
@@ -7550,7 +7552,7 @@ snapshots:
dependencies:
'@changesets/types': 6.1.0
- '@fingerprintjs/changesets-native-dependency-format@0.1.0':
+ '@fingerprintjs/changesets-native-dependency-format@0.2.0':
dependencies:
'@changesets/get-release-plan': 4.0.16
'@changesets/types': 6.1.0
diff --git a/sdk/Package.swift b/sdk/Package.swift
index e56bf3a7..166adebb 100644
--- a/sdk/Package.swift
+++ b/sdk/Package.swift
@@ -68,7 +68,7 @@ let package = Package(
.package(name: "React-GeneratedCode", path: "../../../ios"),
.package(
url: "https://github.com/fingerprintjs/fingerprint-ios",
- from: "4.0.0"
+ .upToNextMinor(from: "4.1.0")
),
],
targets: [
diff --git a/sdk/README.md b/sdk/README.md
index 9077bc86..f902a8bc 100644
--- a/sdk/README.md
+++ b/sdk/README.md
@@ -363,6 +363,26 @@ return (
)
```
+### Custom endpoints
+
+To avoid ad blockers, proxy identification through a [proxy integration](https://docs.fingerprint.com/docs/protecting-the-javascript-agent-from-adblockers). Pass identification URLs as `endpoints`, first to last.
+
+We recommend including the default API URL for your [region](https://docs.fingerprint.com/docs/regions) as a fallback: `https://api.fpjs.io` (US), `https://eu.api.fpjs.io` (EU), `https://ap.api.fpjs.io` (Asia). There are no fallbacks by default.
+
+
+```javascript
+return (
+
+
+
+)
+```
+
## API Reference
See the full [generated API Reference](https://fingerprintjs.github.io/react-native/).
diff --git a/sdk/RNFingerprint.podspec b/sdk/RNFingerprint.podspec
index 0a064222..6800c9ad 100644
--- a/sdk/RNFingerprint.podspec
+++ b/sdk/RNFingerprint.podspec
@@ -20,7 +20,7 @@ Pod::Spec.new do |s|
# s.requires_arc = true
s.dependency "React-Core"
- s.dependency "Fingerprint-iOS", "~> 4.0"
+ s.dependency "Fingerprint-iOS", "~> 4.1.0"
# Wires up the TurboModule/Codegen dependencies (ReactCommon, generated specs, ...) and defines
# `RCT_NEW_ARCH_ENABLED` for the pod when the app is built with the New Architecture.
diff --git a/sdk/android/build.gradle b/sdk/android/build.gradle
index 036f44c4..465be05f 100644
--- a/sdk/android/build.gradle
+++ b/sdk/android/build.gradle
@@ -5,7 +5,11 @@ plugins {
// The SDK supports the New Architecture only. Applying the React Gradle plugin runs library Codegen
// (generates the `NativeRNFingerprintSpec` base class).
-apply plugin: 'com.facebook.react'
+// Only apply when evaluated as a subproject of a host RN app; when run standalone (e.g. CLI tasks like
+// printFingerprintNativeSDKVersion), project == rootProject and the React plugin is not on the classpath.
+if (project != rootProject) {
+ apply plugin: 'com.facebook.react'
+}
apply from: 'fingerprint.gradle'
diff --git a/sdk/android/fingerprint.gradle b/sdk/android/fingerprint.gradle
index 59ec6719..b752995f 100644
--- a/sdk/android/fingerprint.gradle
+++ b/sdk/android/fingerprint.gradle
@@ -1,4 +1,4 @@
-ext.fingerprint_native_sdk_version = "[4.1.0, 5.0.0)"
+ext.fingerprint_native_sdk_version = "[4.1.0, 4.2.0)"
task printFingerprintNativeSDKVersion {
doLast {
diff --git a/sdk/android/src/main/java/com/fingerprint/reactnative/RNFingerprintModule.kt b/sdk/android/src/main/java/com/fingerprint/reactnative/RNFingerprintModule.kt
index c1e8452b..7bec6a6b 100644
--- a/sdk/android/src/main/java/com/fingerprint/reactnative/RNFingerprintModule.kt
+++ b/sdk/android/src/main/java/com/fingerprint/reactnative/RNFingerprintModule.kt
@@ -15,7 +15,6 @@ import com.fingerprint.android.RequestTimeout
import com.fingerprint.android.TooManyRequest
import com.fingerprint.android.WrongRegion
import com.fingerprint.android.SubscriptionNotActive
-import com.fingerprint.android.SubscriptionNotFound
import com.fingerprint.android.SubscriptionRestricted
import com.fingerprint.android.InstallationMethodRestricted
import com.fingerprint.android.EnvironmentRestricted
@@ -132,7 +131,6 @@ class RNFingerprintModule(reactContext: ReactApplicationContext) : NativeRNFinge
is TooManyRequest -> "too_many_requests"
is WrongRegion -> "wrong_region"
is SubscriptionNotActive -> "subscription_not_active"
- is SubscriptionNotFound -> "subscription_not_found"
is SubscriptionRestricted -> "subscription_restricted"
is InstallationMethodRestricted -> "installation_method_restricted"
is EnvironmentRestricted -> "environment_restricted"
diff --git a/sdk/ios/FPError+React.swift b/sdk/ios/FPError+React.swift
index a41bc314..697ab0b8 100644
--- a/sdk/ios/FPError+React.swift
+++ b/sdk/ios/FPError+React.swift
@@ -41,13 +41,13 @@ extension FPError {
var reactMessage: String {
switch self {
case .apiError(let apiError):
- return apiError.message ?? self.localizedDescription
+ return apiError.message ?? self.description
case .networkError(let networkError):
return networkError.localizedDescription
case .jsonParsingError(let jsonParsingError):
return jsonParsingError.localizedDescription
default:
- return self.localizedDescription
+ return self.description
}
}
@@ -88,7 +88,6 @@ extension APIError {
case .visitorNotFound: return "visitor_not_found"
case .tooManyRequests: return "too_many_requests"
case .failed: return "failed"
- case .eventNotFound: return "event_not_found"
case .missingModule: return "missing_module"
case .payloadTooLarge: return "payload_too_large"
case .serviceUnavailable: return "service_unavailable"
@@ -97,7 +96,6 @@ extension APIError {
case .invalidProxyIntegrationHeaders: return "invalid_proxy_integration_headers"
case .subscriptionRestricted: return "subscription_restricted"
case .environmentRestricted: return "environment_restricted"
- case .subscriptionNotFound: return "subscription_not_found"
case .installationMethodRestricted: return "installation_method_restricted"
// A future SDK may add codes; fall back to the raw value rather than losing the information.
@unknown default: return code.rawValue
diff --git a/sdk/src/FingerprintClient.web.ts b/sdk/src/FingerprintClient.web.ts
index 017262d7..2edf69c0 100644
--- a/sdk/src/FingerprintClient.web.ts
+++ b/sdk/src/FingerprintClient.web.ts
@@ -1,6 +1,7 @@
import * as Fingerprint from '@fingerprint/agent'
import type { FingerprintClient, FingerprintResponse, GetOptions, StartOptions } from './types'
import { unwrapError } from './unwrapError'
+import { isEmptyArray, isTruthy } from './utils'
const packageVersion = '__VERSION__'
@@ -13,7 +14,12 @@ const packageVersion = '__VERSION__'
class WebFingerprintClient implements FingerprintClient {
private readonly agent: Fingerprint.Agent
- constructor({ apiKey, region, endpoints, web }: StartOptions) {
+ constructor({ apiKey, region, endpoints: endpointsParam, web }: StartOptions) {
+ const endpoints =
+ isTruthy(endpointsParam) && !isEmptyArray(endpointsParam)
+ ? Fingerprint.withoutDefault(endpointsParam)
+ : endpointsParam
+
this.agent = Fingerprint.start({
apiKey,
region,
diff --git a/sdk/src/errors.ts b/sdk/src/errors.ts
index 2b421633..bd7b9a46 100644
--- a/sdk/src/errors.ts
+++ b/sdk/src/errors.ts
@@ -27,7 +27,6 @@ export type ErrorCode =
| 'wrong_region'
| 'feature_not_enabled'
| 'visitor_not_found'
- | 'event_not_found'
| 'missing_module'
| 'payload_too_large'
| 'service_unavailable'
diff --git a/sdk/src/utils.ts b/sdk/src/utils.ts
index 833c17b6..93b2b071 100644
--- a/sdk/src/utils.ts
+++ b/sdk/src/utils.ts
@@ -6,6 +6,10 @@ export function isTruthy(value?: T | null): value is T {
return Boolean(value)
}
+export function isEmptyArray(value: unknown): value is [] {
+ return Array.isArray(value) && value.length === 0
+}
+
function isObject(value: unknown): value is Record {
return typeof value === 'object' && value !== null
}