diff --git a/CHANGELOG.md b/CHANGELOG.md
index d822305..a0b123a 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,13 @@
+## 1.7.0
+
+- Updated iOS SDK
+ to [4.5.1](https://github.com/Keyri-Co/keyri-ios-whitelabel-sdk/releases/tag/4.5.1)
+- Updated Android SDK
+ to [4.2.3](https://github.com/Keyri-Co/keyri-android-whitelabel-sdk/releases/tag/4.2.3)
+- Added new `createFingerprint` method
+- Fixed timestamp length on Android
+- Updated events structure and dded metadata field
+
## 1.6.2
- Updated plugin_platform_interface and bump example dependencies
@@ -7,7 +17,7 @@
- Updated iOS SDK
to [4.4.1](https://github.com/Keyri-Co/keyri-ios-whitelabel-sdk/releases/tag/4.4.1)
- Updated Android SDK
- to [4.1.1](https://github.com/Keyri-Co/keyri-android-whitelabel-sdk-source/releases/tag/4.1.1)
+ to [4.1.1](https://github.com/Keyri-Co/keyri-android-whitelabel-sdk/releases/tag/4.1.1)
- Fixed nullable publicUserId in `login` and `register` methods on Android
- Updated proguard-rules to keep `LoginObject` and `RegisterObject` on Android
- Fixed passing `appKey` on iOS initialize
diff --git a/android/build.gradle b/android/build.gradle
index eb2016c..b855028 100644
--- a/android/build.gradle
+++ b/android/build.gradle
@@ -48,8 +48,8 @@ android {
dependencies {
// Keyri
- implementation 'com.keyri:keyrisdk:4.1.1'
- implementation 'com.keyri:scanner:4.1.1'
+ implementation 'com.keyri:keyrisdk:4.2.3'
+ implementation 'com.keyri:scanner:4.2.3'
// Gson
implementation 'com.google.code.gson:gson:2.10.1'
diff --git a/android/src/main/kotlin/com/keyrico/keyri/KeyriPlugin.kt b/android/src/main/kotlin/com/keyrico/keyri/KeyriPlugin.kt
index a92faae..2b2ecc9 100644
--- a/android/src/main/kotlin/com/keyrico/keyri/KeyriPlugin.kt
+++ b/android/src/main/kotlin/com/keyrico/keyri/KeyriPlugin.kt
@@ -6,10 +6,11 @@ import android.util.Log
import android.app.Activity
import android.content.Intent
import com.google.gson.Gson
+import org.json.JSONObject
import com.keyrico.keyrisdk.Keyri
import com.keyrico.scanner.easyKeyriAuth
import com.keyrico.keyrisdk.exception.DenialException
-import com.keyrico.keyrisdk.sec.fraud.enums.EventType
+import com.keyrico.keyrisdk.sec.fraud.event.EventType
import androidx.fragment.app.FragmentActivity
import com.keyrico.keyrisdk.entity.session.Session
import io.flutter.embedding.android.FlutterFragmentActivity
@@ -128,10 +129,16 @@ class KeyriPlugin : FlutterPlugin, MethodCallHandler, ActivityAware,
"sendEvent" -> {
val publicUserId = arguments?.get("publicUserId")
val eventType = arguments?.get("eventType")
+ val metadata = arguments?.get("metadata")
val success = arguments?.get("success")?.toBoolean()
logMessage("Keyri: sendEvent called")
- sendEvent(publicUserId, eventType, success, result)
+ sendEvent(publicUserId, eventType, metadata, success, result)
+ }
+
+ "createFingerprint" -> {
+ logMessage("Keyri: createFingerprint called")
+ createFingerprint(result)
}
"initiateQrSession" -> {
@@ -357,11 +364,13 @@ class KeyriPlugin : FlutterPlugin, MethodCallHandler, ActivityAware,
private fun sendEvent(
publicUserId: String?,
eventType: String?,
+ metadata: String?,
success: Boolean?,
result: MethodChannel.Result
) {
keyriCoroutineScope("sendEvent", result::error).launch {
- val type = EventType.values().firstOrNull { it.type == eventType }
+ val jsonMetadata = metadata?.let(::JSONObject)
+ val type = eventType?.let { EventType.custom(it, jsonMetadata) }
if (success == null) {
logMessage("Keyri sendEvent: success must not be null")
@@ -385,6 +394,20 @@ class KeyriPlugin : FlutterPlugin, MethodCallHandler, ActivityAware,
}
}
+ private fun createFingerprint(result: MethodChannel.Result) {
+ keyriCoroutineScope("createFingerprint", result::error).launch {
+ keyri.createFingerprint().onSuccess { fingerprint ->
+ val fingerprintResponse = Gson().toJson(fingerprint)
+
+ logMessage("Keyri createFingerprint: $fingerprintResponse")
+ result.success(fingerprintResponse)
+ }.onFailure {
+ logMessage("Keyri createFingerprint: ${it.message}")
+ result.error("createFingerprint", it.message, null)
+ }
+ }
+ }
+
private fun initiateQrSession(
sessionId: String?,
publicUserId: String?,
diff --git a/example/ios/Flutter/AppFrameworkInfo.plist b/example/ios/Flutter/AppFrameworkInfo.plist
index 9625e10..7c56964 100644
--- a/example/ios/Flutter/AppFrameworkInfo.plist
+++ b/example/ios/Flutter/AppFrameworkInfo.plist
@@ -21,6 +21,6 @@
CFBundleVersion
1.0
MinimumOSVersion
- 11.0
+ 12.0
diff --git a/example/ios/Runner.xcodeproj/project.pbxproj b/example/ios/Runner.xcodeproj/project.pbxproj
index 27fb470..8fba1d3 100644
--- a/example/ios/Runner.xcodeproj/project.pbxproj
+++ b/example/ios/Runner.xcodeproj/project.pbxproj
@@ -154,7 +154,7 @@
97C146E61CF9000F007C117D /* Project object */ = {
isa = PBXProject;
attributes = {
- LastUpgradeCheck = 1430;
+ LastUpgradeCheck = 1510;
ORGANIZATIONNAME = "";
TargetAttributes = {
97C146ED1CF9000F007C117D = {
diff --git a/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme
index a6b826d..5e31d3d 100644
--- a/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme
+++ b/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme
@@ -1,6 +1,6 @@
{
- EventType? _eventType = EventType.visits;
+ final EventType _eventType = EventType.visits();
@override
Widget build(BuildContext context) {
@@ -91,21 +91,6 @@ class _KeyriHomePageState extends State {
),
),
),
- DropdownButton(
- items: EventType.values
- .map>((EventType value) {
- return DropdownMenuItem(
- value: value,
- child: Text(value.name),
- );
- }).toList(),
- onChanged: (value) {
- setState(() {
- _eventType = value;
- });
- },
- value: _eventType,
- ),
button(_sendEvent, 'Send event'),
button(_login, 'Login'),
button(_register, 'Register'),
@@ -290,7 +275,7 @@ class _KeyriHomePageState extends State {
keyri
.sendEvent(
publicUserId: usernameController.text,
- eventType: _eventType ?? EventType.visits,
+ eventType: _eventType,
success: true)
.then((fingerprintEventResponse) => _showMessage("Event sent"))
.catchError((error, stackTrace) => _processError(error));
diff --git a/example/pubspec.yaml b/example/pubspec.yaml
index 85dbe6d..250dcd4 100644
--- a/example/pubspec.yaml
+++ b/example/pubspec.yaml
@@ -1,5 +1,5 @@
name: keyri_example
-version: 1.6.2
+version: 1.7.0
description: Demonstrates how to use the Keyri plugin.
publish_to: 'none'
@@ -8,7 +8,7 @@ environment:
dependencies:
flutter:
sdk: flutter
- http: ^1.2.0
+ http: ^1.2.1
keyri_v3:
path: ../
cupertino_icons: ^1.0.6
diff --git a/ios/Classes/KeyriPlugin.m b/ios/Classes/KeyriPlugin.m
index 0468138..ff8e1db 100644
--- a/ios/Classes/KeyriPlugin.m
+++ b/ios/Classes/KeyriPlugin.m
@@ -45,6 +45,8 @@ - (void)handleMethodCall:(FlutterMethodCall*)call result:(FlutterResult)result {
[self removeAssociationKey:call result:result];
} else if ([@"sendEvent" isEqualToString:call.method]) {
[self sendEvent:call result:result];
+ } else if ([@"createFingerprint" isEqualToString:call.method]) {
+ [self sendEvent:call result:result];
} else if ([@"initiateQrSession" isEqualToString:call.method]) {
[self initiateQrSession:call result:result];
} else if ([@"login" isEqualToString:call.method]) {
@@ -177,6 +179,7 @@ - (void)removeAssociationKey:(FlutterMethodCall*)call result:(FlutterResult)resu
- (void)sendEvent:(FlutterMethodCall*)call result:(FlutterResult)result {
id publicUserIdValue = call.arguments[@"publicUserId"];
id eventType = call.arguments[@"eventType"];
+ id metadata = call.arguments[@"metadata"];
id successValue = call.arguments[@"success"];
NSString *publicUserId = [publicUserIdValue isKindOfClass:[NSString class]] ? publicUserIdValue : nil;
@@ -193,8 +196,15 @@ - (void)sendEvent:(FlutterMethodCall*)call result:(FlutterResult)result {
return [self sendErrorResult:result errorMessage:@"You need to provide eventType"];
}
+ NSData *jsonData = [metadata dataUsingEncoding:NSUTF8StringEncoding];
+
+ NSError *error = nil;
+ NSDictionary *metadataDictionary = [NSJSONSerialization JSONObjectWithData:jsonData options:NSJSONReadingMutableContainers error:&error];
+
+ EventType *event = [EventType customWithName:eventType metadata:metadataDictionary];
+
__weak typeof (self) weakSelf = self;
- [self.keyri sendEventWithPublicUserId:publicUserId eventType:eventType success:success completion:^(FingerprintResponse * _Nullable fingerprintResponse, NSError * _Nullable error) {
+ [self.keyri sendEventWithPublicUserId:publicUserId eventType:event success:success completion:^(FingerprintResponse * _Nullable fingerprintResponse, NSError * _Nullable error) {
typeof (self) strongSelf = weakSelf;
if (error != nil) {
@@ -209,6 +219,20 @@ - (void)sendEvent:(FlutterMethodCall*)call result:(FlutterResult)result {
}];
}
+- (void)createFingerprint:(FlutterMethodCall*)call result:(FlutterResult)result {
+ [self.keyri createFingerprintWithCompletion:^(FingerprintRequest * _Nullable fingerprint, NSError * _Nullable error) {
+ if (error != nil) {
+ return result([FlutterError errorWithCode:@"1" message:error.localizedDescription details:nil]);
+ }
+
+ if (fingerprint != nil) {
+ return result([self dictionaryWithPropertiesOfObject:fingerprint]);
+ } else {
+ return [self sendErrorResult:result errorMessage:@"FingerprintRequest is nil"];
+ }
+ }];
+}
+
- (void)initiateQrSession:(FlutterMethodCall*)call result:(FlutterResult)result {
id sessionId = call.arguments[@"sessionId"];
id publicUserIdValue = call.arguments[@"publicUserId"];
diff --git a/ios/keyri_v3.podspec b/ios/keyri_v3.podspec
index ae45a53..39fa7dd 100644
--- a/ios/keyri_v3.podspec
+++ b/ios/keyri_v3.podspec
@@ -18,7 +18,7 @@ Pod::Spec.new do |spec|
spec.public_header_files = 'Classes/**/*.h'
spec.dependency 'Flutter'
- spec.dependency 'keyri-pod', '~> 4.4.1'
+ spec.dependency 'keyri-pod', '~> 4.5.1'
# Flutter.framework does not contain a i386 slice.
spec.pod_target_xcconfig = { 'DEFINES_MODULE' => 'YES', 'EXCLUDED_ARCHS[sdk=iphonesimulator*]' => 'i386' }
diff --git a/lib/fingerprint_request.dart b/lib/fingerprint_request.dart
new file mode 100644
index 0000000..4319761
--- /dev/null
+++ b/lib/fingerprint_request.dart
@@ -0,0 +1,30 @@
+import 'dart:convert';
+
+/// Class which represents fingerprint request object.
+class FingerprintRequest {
+ FingerprintRequest(
+ this.clientEncryptionKey, this.encryptedPayload, this.salt, this.iv);
+
+ final String clientEncryptionKey;
+ final String encryptedPayload;
+ final String salt;
+ final String iv;
+
+ /// Conversion helper method.
+ static FingerprintRequest fromJson(dynamic json) {
+ dynamic jsonData = json;
+
+ try {
+ String jsonDataString = json.toString();
+ jsonData = jsonDecode(jsonDataString);
+ } catch (e) {
+ jsonData = json;
+ }
+
+ return FingerprintRequest(
+ jsonData['clientEncryptionKey'] as String,
+ jsonData['encryptedPayload'] as String,
+ jsonData['salt'] as String,
+ jsonData['iv'] as String);
+ }
+}
diff --git a/lib/keyri.dart b/lib/keyri.dart
index 69c8f83..c706aa7 100644
--- a/lib/keyri.dart
+++ b/lib/keyri.dart
@@ -1,4 +1,5 @@
import 'package:keyri_v3/fingerprint_event_response.dart';
+import 'package:keyri_v3/fingerprint_request.dart';
import 'package:keyri_v3/register_object.dart';
import 'package:keyri_v3/session.dart';
import 'keyri_fingerprint_event.dart';
@@ -78,7 +79,7 @@ class Keyri {
}
/// Sends fingerprint event and event result for specified publicUserId's.
- /// Return [FingerprintEventResponse] or error.
+ /// Returns [FingerprintEventResponse] or error.
Future sendEvent(
{String? publicUserId,
required EventType eventType,
@@ -86,6 +87,12 @@ class Keyri {
return KeyriPlatform.instance.sendEvent(publicUserId, eventType, success);
}
+ /// Creates and returns fingerprint event object.
+ /// Returns [FingerprintRequest] or error.
+ Future createFingerprint() {
+ return KeyriPlatform.instance.createFingerprint();
+ }
+
/// Call it after obtaining the sessionId from QR code or deep link.
/// Returns Future of [Session] object with Risk attributes (needed to show confirmation screen) or error.
Future initiateQrSession(String sessionId, {String? publicUserId}) {
diff --git a/lib/keyri_fingerprint_event.dart b/lib/keyri_fingerprint_event.dart
index 7d40fee..d170f2d 100644
--- a/lib/keyri_fingerprint_event.dart
+++ b/lib/keyri_fingerprint_event.dart
@@ -1,14 +1,51 @@
-// ignore_for_file: constant_identifier_names
-/// Fingerprint event type.
-enum EventType {
- visits,
- login,
- signup,
- attach_new_device,
- email_change,
- profile_update,
- password_reset,
- withdrawal,
- deposit,
- purchase;
+/// Class which represents fingerprint event type.
+class EventType {
+ EventType(this.name, {this.metadata});
+
+ final String name;
+ Map? metadata;
+
+ /// Returns Visits event.
+ static EventType visits({Map? metadata}) =>
+ EventType("visits", metadata: metadata);
+
+ /// Returns Login event.
+ static EventType login({Map? metadata}) =>
+ EventType("login", metadata: metadata);
+
+ /// Returns signup event.
+ static EventType signup({Map? metadata}) =>
+ EventType("signup", metadata: metadata);
+
+ /// Returns Attach new device event.
+ static EventType attachNewDevice({Map? metadata}) =>
+ EventType("attach_new_device", metadata: metadata);
+
+ /// Returns Email change event.
+ static EventType emailChange({Map? metadata}) =>
+ EventType("emailChange", metadata: metadata);
+
+ /// Returns Profile update event.
+ static EventType profileUpdate({Map? metadata}) =>
+ EventType("profile_update", metadata: metadata);
+
+ /// Returns Password reset event.
+ static EventType passwordReset({Map? metadata}) =>
+ EventType("password_reset", metadata: metadata);
+
+ /// Returns Withdrawal event.
+ static EventType withdrawal({Map? metadata}) =>
+ EventType("withdrawal", metadata: metadata);
+
+ /// Returns Deposit event.
+ static EventType deposit({Map? metadata}) =>
+ EventType("deposit", metadata: metadata);
+
+ /// Returns Purchase event.
+ static EventType purchase({Map? metadata}) =>
+ EventType("purchase", metadata: metadata);
+
+ /// Returns Custom event.
+ static EventType custom(String name, {Map? metadata}) =>
+ EventType(name, metadata: metadata);
}
diff --git a/lib/src/keyri_method_channel.dart b/lib/src/keyri_method_channel.dart
index 3454b14..5dc7bed 100644
--- a/lib/src/keyri_method_channel.dart
+++ b/lib/src/keyri_method_channel.dart
@@ -1,6 +1,9 @@
+import 'dart:convert';
+
import 'package:flutter/foundation.dart';
import 'package:flutter/services.dart';
import 'package:keyri_v3/fingerprint_event_response.dart';
+import 'package:keyri_v3/fingerprint_request.dart';
import 'package:keyri_v3/session.dart';
import '../keyri_fingerprint_event.dart';
import '../login_object.dart';
@@ -108,12 +111,21 @@ class MethodChannelKeyri extends KeyriPlatform {
await methodChannel.invokeMethod('sendEvent', {
'publicUserId': publicUserId,
'eventType': eventType.name,
+ 'metadata': json.encode(eventType.metadata),
'success': success.toString()
});
return FingerprintEventResponse.fromJson(fingerprintEventResponseObject);
}
+ @override
+ Future createFingerprint() async {
+ dynamic fingerprintRequestObject =
+ await methodChannel.invokeMethod('createFingerprint');
+
+ return FingerprintRequest.fromJson(fingerprintRequestObject);
+ }
+
@override
Future initiateQrSession(
String sessionId, String? publicUserId) async {
diff --git a/lib/src/keyri_platform_interface.dart b/lib/src/keyri_platform_interface.dart
index 24d2d43..1125fe9 100644
--- a/lib/src/keyri_platform_interface.dart
+++ b/lib/src/keyri_platform_interface.dart
@@ -1,3 +1,4 @@
+import 'package:keyri_v3/fingerprint_request.dart';
import 'package:keyri_v3/session.dart';
import 'package:plugin_platform_interface/plugin_platform_interface.dart';
@@ -75,6 +76,10 @@ abstract class KeyriPlatform extends PlatformInterface {
throw UnimplementedError('sendEvent() has not been implemented.');
}
+ Future createFingerprint() {
+ throw UnimplementedError('createFingerprint() has not been implemented.');
+ }
+
Future initiateQrSession(String sessionId, String? publicUserId) {
throw UnimplementedError('initiateQrSession() has not been implemented.');
}
diff --git a/pubspec.yaml b/pubspec.yaml
index a7f90c5..f75f0d7 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -1,11 +1,11 @@
name: keyri_v3
description: Keyri QR Login plugin for Flutter. Provides Keyri SDK capabilities for secure and passwordless login.
-version: 1.6.2
+version: 1.7.0
homepage: https://keyri.com
environment:
sdk: '>=2.18.0 <4.0.0'
- flutter: '>=2.5.0'
+ flutter: '>=2.8.0'
dependencies:
flutter: