Skip to content

Commit

Permalink
Merge pull request #75 from fingerprintjs/add-endpoint-fallback-suppo…
Browse files Browse the repository at this point in the history
…rt-INTER-832

Add endpoint fallback support-prerelease
  • Loading branch information
ilfa authored Aug 22, 2024
2 parents c7126d6 + 64c9824 commit a0e107b
Show file tree
Hide file tree
Showing 10 changed files with 72 additions and 50 deletions.
6 changes: 4 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -89,15 +89,17 @@ class _MyAppState extends State<MyApp> {
}
```

You can also configure `region` and `endpoint` in the `initFpjs` method, like below. For the web platform, you can use an additional `scriptUrlPattern` property to specify a custom URL for loading the JavaScript agent. This is required for proxy integrations.
You can also configure `region`, `endpoint` and `endpointFallbacks` in the `initFpjs` method, like below. For the web platform, you can use an additional `scriptUrlPattern` and `scriptUrlPatternFallbacks` properties to specify a custom URL for loading the JavaScript agent. This is required for proxy integrations.
```dart
void doInit() async {
await FpjsProPlugin.initFpjs(
'<apiKey>',
endpoint: 'https://subdomain.domain.com',
endpointFallbacks: ['https://subdomain2.domain.com', 'https://subdomain3.domain.com'],
region: Region.eu, // or Region.ap, Region.us
// Only necessary for the web platform
scriptUrlPattern: 'https://your.domain/fp_js/script_path?apiKey=<apiKey>&version=<version>&loaderVersion=<loaderVersion>'
scriptUrlPattern: 'https://your.domain/fp_js/script_path?apiKey=<apiKey>&version=<version>&loaderVersion=<loaderVersion>',
scriptUrlPatternFallbacks: ['https://your.second-domain/fp_js/script_path?apiKey=<apiKey>&version=<version>&loaderVersion=<loaderVersion>']
);
}
```
Expand Down
2 changes: 1 addition & 1 deletion android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -53,5 +53,5 @@ android {

dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
implementation "com.fingerprint.android:pro:2.4.0"
implementation "com.fingerprint.android:pro:2.5.0"
}
Original file line number Diff line number Diff line change
Expand Up @@ -59,11 +59,12 @@ class FpjsProPlugin: FlutterPlugin, MethodCallHandler {

val regionString = call.argument<String>("region")
val endpoint = call.argument<String>("endpoint")
val endpointFallbacks = call.argument<List<String>?>("endpointFallbacks")
val region = regionString?.let { parseRegion(it) }
val extendedResponseFormat = call.argument<Boolean>("extendedResponseFormat") ?: false
val pluginVersion = call.argument<String>("pluginVersion") ?: "unknown"

initFpjs(token, region, endpoint, extendedResponseFormat, pluginVersion)
initFpjs(token, region, endpoint, endpointFallbacks, extendedResponseFormat, pluginVersion)
result.success("Successfully initialized FingerprintJS Pro Client")
}
GET_VISITOR_ID -> {
Expand Down Expand Up @@ -94,13 +95,14 @@ class FpjsProPlugin: FlutterPlugin, MethodCallHandler {
channel.setMethodCallHandler(null)
}

private fun initFpjs(apiToken: String, region: Configuration.Region?, endpoint: String?, extendedResponseFormat: Boolean, pluginVersion: String) {
private fun initFpjs(apiToken: String, region: Configuration.Region?, endpoint: String?, endpointFallbacks:List<String>?, extendedResponseFormat: Boolean, pluginVersion: String) {
val factory = FingerprintJSFactory(applicationContext)
val configuration = Configuration(
apiToken,
region ?: Configuration.Region.US,
endpoint ?: region?.endpointUrl ?: Configuration.Region.US.endpointUrl,
extendedResponseFormat,
endpointFallbacks ?: emptyList(),
listOf(Pair("fingerprintjs-pro-flutter", pluginVersion))
)

Expand Down Expand Up @@ -171,4 +173,4 @@ private fun getErrorCode(error: Error): String {
else -> "UnknownError"
}
return errorType
}
}
12 changes: 6 additions & 6 deletions example/ios/Podfile.lock
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
PODS:
- FingerprintPro (2.4.0)
- FingerprintPro (2.6.0)
- Flutter (1.0.0)
- fpjs_pro_plugin (2.1.1):
- FingerprintPro (~> 2.4.0)
- fpjs_pro_plugin (3.0.1):
- FingerprintPro (~> 2.6.0)
- Flutter

DEPENDENCIES:
Expand All @@ -20,10 +20,10 @@ EXTERNAL SOURCES:
:path: ".symlinks/plugins/fpjs_pro_plugin/ios"

SPEC CHECKSUMS:
FingerprintPro: 550396e390f81754a6ca13991131ea28952c4e48
FingerprintPro: 3f06f491c77d871ab543b49fd25fddc52dc34f8c
Flutter: e0871f40cf51350855a761d2e70bf5af5b9b5de7
fpjs_pro_plugin: eca9d74d04a70d6ac1549d81fdae224940279c3a
fpjs_pro_plugin: 83f30abadcd58450a80c6ef5837f5e914d7ce238

PODFILE CHECKSUM: 2f1a6d2470f392e010cfe7ae5f9f694d8487db82

COCOAPODS: 1.14.3
COCOAPODS: 1.15.2
50 changes: 29 additions & 21 deletions example/lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import 'dart:async';
import 'dart:convert';

import 'package:env_flutter/env_flutter.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:fpjs_pro_plugin/error.dart';
import 'package:fpjs_pro_plugin/fpjs_pro_plugin.dart';
Expand Down Expand Up @@ -39,7 +38,7 @@ class _MyAppState extends State<MyApp> {
dotenv.env['PROXY_INTEGRATION_PATH'] ?? 'no_proxy_integration';
final String _proxyIntegrationRequestPath =
dotenv.env['PROXY_INTEGRATION_REQUEST_PATH'] ?? 'no_proxy_integration';
final String? _proxyIntegrationScriptPath =
final String _proxyIntegrationScriptPath =
dotenv.env['PROXY_INTEGRATION_SCRIPT_PATH'] ?? 'no_proxy_integration';
final String _region = dotenv.env['REGION'] ?? 'us';

Expand Down Expand Up @@ -133,8 +132,8 @@ class _MyAppState extends State<MyApp> {
linkedId: 'checkDataWithTag', tags: tags),
];

for (var _check in checks) {
await _check();
for (var check in checks) {
await check();
setState(() {
_checksResult += '.';
});
Expand Down Expand Up @@ -176,28 +175,37 @@ class _ExtendedResultDialog extends StatelessWidget {
const _ExtendedResultDialog({Key? key, required this.handleIdentificate})
: super(key: key);

final AsyncCallback handleIdentificate;
final Future<String> Function() handleIdentificate;

@override
Widget build(BuildContext context) {
return ElevatedButton(
onPressed: () => {
handleIdentificate().then((identificationInfo) => showDialog<String>(
context: context,
builder: (BuildContext context) => AlertDialog(
title: const Text('Extended result'),
content: FittedBox(
fit: BoxFit.contain,
child: Text(identificationInfo as String),
),
actions: <Widget>[
ElevatedButton(
onPressed: () => Navigator.pop(context, 'OK'),
child: const Text('OK'),
),
],
onPressed: () async {
final resultContext = context;
String identificationInfo;
try {
identificationInfo = await handleIdentificate();
} catch (e) {
identificationInfo = 'Identification error: $e';
}
if (resultContext.mounted) {
showDialog<String>(
context: resultContext,
builder: (BuildContext context) => AlertDialog(
title: const Text('Extended result'),
content: FittedBox(
fit: BoxFit.contain,
child: Text(identificationInfo),
),
))
actions: <Widget>[
ElevatedButton(
onPressed: () => Navigator.pop(context, 'OK'),
child: const Text('OK'),
),
],
),
);
}
},
child: const Text('Identify with extended result!'),
);
Expand Down
20 changes: 10 additions & 10 deletions ios/Classes/SwiftFpjsProPlugin.swift
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,10 @@ public class SwiftFpjsProPlugin: NSObject, FlutterPlugin {
result(FlutterError(code: "missingArguments", message: "Missing or invalid arguments", details: nil))
return
}

if (call.method == "init") {
if let token = args["apiToken"] as? String {
let region = parseRegion(passedRegion: args["region"] as? String, endpoint: args["endpoint"] as? String)
let region = parseRegion(passedRegion: args["region"] as? String, endpoint: args["endpoint"] as? String, endpointFallbacks: args["endpointFallbacks"] as? [String] ?? [])
let extendedResponseFormat = args["extendedResponseFormat"] as? Bool ?? false
let pluginVersion = args["pluginVersion"] as? String ?? "unknown"

Expand All @@ -36,7 +36,7 @@ public class SwiftFpjsProPlugin: NSObject, FlutterPlugin {
getVisitorData(metadata, result)
}
}

private func prepareMetadata(_ linkedId: String?, tags: Any?) -> Metadata {
var metadata = Metadata(linkedId: linkedId)
guard
Expand All @@ -45,7 +45,7 @@ public class SwiftFpjsProPlugin: NSObject, FlutterPlugin {
else {
return metadata
}

if let dict = jsonTags as? [String: JSONTypeConvertible] {
dict.forEach { key, jsonType in
metadata.setTag(jsonType, forKey: key)
Expand All @@ -56,7 +56,7 @@ public class SwiftFpjsProPlugin: NSObject, FlutterPlugin {
return metadata
}

private func parseRegion(passedRegion: String?, endpoint: String?) -> Region {
private func parseRegion(passedRegion: String?, endpoint: String?, endpointFallbacks: [String]) -> Region {
var region: Region
switch passedRegion {
case "eu":
Expand All @@ -68,7 +68,7 @@ public class SwiftFpjsProPlugin: NSObject, FlutterPlugin {
}

if let endpointString = endpoint {
region = .custom(domain: endpointString)
region = .custom(domain: endpointString, fallback: endpointFallbacks)
}

return region
Expand All @@ -84,7 +84,7 @@ public class SwiftFpjsProPlugin: NSObject, FlutterPlugin {
result(FlutterError.init(code: "undefinedFpClient", message: "You need to call init method first", details: nil))
return
}

client.getVisitorId(metadata) { visitorIdResult in
switch visitorIdResult {
case .success(let visitorId):
Expand All @@ -94,13 +94,13 @@ public class SwiftFpjsProPlugin: NSObject, FlutterPlugin {
}
}
}

private func getVisitorData(_ metadata: Metadata?, _ result: @escaping FlutterResult) {
guard let client = fpjsClient else {
result(FlutterError(code: "undefinedFpClient", message: "You need to call init method first", details: nil))
return
}

client.getVisitorIdResponse(metadata) { visitorIdResponseResult in
switch visitorIdResponseResult {
case .success(let visitorDataResponse):
Expand All @@ -114,7 +114,7 @@ public class SwiftFpjsProPlugin: NSObject, FlutterPlugin {
}
}
}

private func processNativeLibraryError(_ error: FPJSError, result: @escaping FlutterResult) {
let (code, description) = error.flutterFields
result(FlutterError(code: code, message: description, details: nil))
Expand Down
2 changes: 1 addition & 1 deletion ios/fpjs_pro_plugin.podspec
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ Flutter plugin for FingerprintJS Pro.
s.source = { :path => '.' }
s.source_files = 'Classes/**/*'
s.dependency 'Flutter'
s.dependency 'FingerprintPro', '~> 2.4.0'
s.dependency 'FingerprintPro', '~> 2.6.0'

s.platform = :ios, '13.0'

Expand Down
4 changes: 4 additions & 0 deletions lib/fpjs_pro_plugin.dart
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,17 @@ class FpjsProPlugin {
/// Throws a [PlatformException] if [apiKey] is missing
static Future<void> initFpjs(String apiKey,
{String? endpoint,
List<String>? endpointFallbacks,
String? scriptUrlPattern,
List<String>? scriptUrlPatternFallbacks,
Region? region,
bool extendedResponseFormat = false}) async {
await _channel.invokeMethod('init', {
'apiToken': apiKey,
'endpoint': endpoint,
'endpointFallbacks': endpointFallbacks,
'scriptUrlPattern': scriptUrlPattern,
'scriptUrlPatternFallbacks': scriptUrlPatternFallbacks,
'region': region?.stringValue,
'extendedResponseFormat': extendedResponseFormat,
'pluginVersion': pluginVersion,
Expand Down
10 changes: 8 additions & 2 deletions lib/fpjs_pro_plugin_web.dart
Original file line number Diff line number Diff line change
Expand Up @@ -69,10 +69,16 @@ class FpjsProPluginWeb {
options.region = call.arguments['region'];
}
if (call.arguments['endpoint'] != null) {
options.endpoint = call.arguments['endpoint'];
options.endpoint = [
call.arguments['endpoint'],
...(call.arguments['endpointFallbacks'] ?? [])
];
}
if (call.arguments['scriptUrlPattern'] != null) {
options.scriptUrlPattern = call.arguments['scriptUrlPattern'];
options.scriptUrlPattern = [
call.arguments['scriptUrlPattern'],
...(call.arguments['scriptUrlPatternFallbacks'] ?? [])
];
}
try {
_fpPromise = promiseToFuture(FingerprintJS.load(options));
Expand Down
8 changes: 4 additions & 4 deletions lib/js_agent_interop.dart
Original file line number Diff line number Diff line change
Expand Up @@ -211,17 +211,17 @@ class FingerprintJSOptions {
external set region(String? region);

/// Your custom API endpoint for getting visitor data.
external String? get endpoint;
external set endpoint(String? endpoint);
external List<String>? get endpoint;
external set endpoint(List<String>? endpoint);

/// A JS agent script URL pattern.
///
/// The following substrings are replaced:
/// - <version> — the major version of JS agent;
/// - <apiKey> — the public key set via the `apiKey` option;
/// - <loaderVersion> — the version of this package;
external String? get scriptUrlPattern;
external set scriptUrlPattern(String? scriptUrlPattern);
external List<String>? get scriptUrlPattern;
external set scriptUrlPattern(List<String>? scriptUrlPattern);

external factory FingerprintJSOptions(
{String apiKey, List<String> integrationInfo});
Expand Down

0 comments on commit a0e107b

Please sign in to comment.