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 }