Skip to content

Commit

Permalink
Merge pull request #29 from Keyri-Co/feature/new_event_structure
Browse files Browse the repository at this point in the history
Updated SDK-s, added new `createFingerprint` method, updated Events s…
  • Loading branch information
AndrewKuliahin96 authored Feb 22, 2024
2 parents ccd8753 + 5c5ffcd commit de89d05
Show file tree
Hide file tree
Showing 16 changed files with 179 additions and 46 deletions.
12 changes: 11 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -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
Expand Down
4 changes: 2 additions & 2 deletions android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -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'
Expand Down
29 changes: 26 additions & 3 deletions android/src/main/kotlin/com/keyrico/keyri/KeyriPlugin.kt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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" -> {
Expand Down Expand Up @@ -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")
Expand All @@ -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?,
Expand Down
2 changes: 1 addition & 1 deletion example/ios/Flutter/AppFrameworkInfo.plist
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,6 @@
<key>CFBundleVersion</key>
<string>1.0</string>
<key>MinimumOSVersion</key>
<string>11.0</string>
<string>12.0</string>
</dict>
</plist>
2 changes: 1 addition & 1 deletion example/ios/Runner.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@
97C146E61CF9000F007C117D /* Project object */ = {
isa = PBXProject;
attributes = {
LastUpgradeCheck = 1430;
LastUpgradeCheck = 1510;
ORGANIZATIONNAME = "";
TargetAttributes = {
97C146ED1CF9000F007C117D = {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1430"
LastUpgradeVersion = "1510"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
Expand Down
19 changes: 2 additions & 17 deletions example/lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ class KeyriHomePage extends StatefulWidget {
}

class _KeyriHomePageState extends State<KeyriHomePage> {
EventType? _eventType = EventType.visits;
final EventType _eventType = EventType.visits();

@override
Widget build(BuildContext context) {
Expand Down Expand Up @@ -91,21 +91,6 @@ class _KeyriHomePageState extends State<KeyriHomePage> {
),
),
),
DropdownButton<EventType>(
items: EventType.values
.map<DropdownMenuItem<EventType>>((EventType value) {
return DropdownMenuItem<EventType>(
value: value,
child: Text(value.name),
);
}).toList(),
onChanged: (value) {
setState(() {
_eventType = value;
});
},
value: _eventType,
),
button(_sendEvent, 'Send event'),
button(_login, 'Login'),
button(_register, 'Register'),
Expand Down Expand Up @@ -290,7 +275,7 @@ class _KeyriHomePageState extends State<KeyriHomePage> {
keyri
.sendEvent(
publicUserId: usernameController.text,
eventType: _eventType ?? EventType.visits,
eventType: _eventType,
success: true)
.then((fingerprintEventResponse) => _showMessage("Event sent"))
.catchError((error, stackTrace) => _processError(error));
Expand Down
4 changes: 2 additions & 2 deletions example/pubspec.yaml
Original file line number Diff line number Diff line change
@@ -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'

Expand All @@ -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
Expand Down
26 changes: 25 additions & 1 deletion ios/Classes/KeyriPlugin.m
Original file line number Diff line number Diff line change
Expand Up @@ -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]) {
Expand Down Expand Up @@ -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;
Expand All @@ -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) {
Expand All @@ -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"];
Expand Down
2 changes: 1 addition & 1 deletion ios/keyri_v3.podspec
Original file line number Diff line number Diff line change
Expand Up @@ -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' }
Expand Down
30 changes: 30 additions & 0 deletions lib/fingerprint_request.dart
Original file line number Diff line number Diff line change
@@ -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);
}
}
9 changes: 8 additions & 1 deletion lib/keyri.dart
Original file line number Diff line number Diff line change
@@ -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';
Expand Down Expand Up @@ -78,14 +79,20 @@ class Keyri {
}

/// Sends fingerprint event and event result for specified publicUserId's.
/// Return [FingerprintEventResponse] or error.
/// Returns [FingerprintEventResponse] or error.
Future<FingerprintEventResponse> sendEvent(
{String? publicUserId,
required EventType eventType,
required bool success}) {
return KeyriPlatform.instance.sendEvent(publicUserId, eventType, success);
}

/// Creates and returns fingerprint event object.
/// Returns [FingerprintRequest] or error.
Future<FingerprintRequest> 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<Session> initiateQrSession(String sessionId, {String? publicUserId}) {
Expand Down
63 changes: 50 additions & 13 deletions lib/keyri_fingerprint_event.dart
Original file line number Diff line number Diff line change
@@ -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<String, dynamic>? metadata;

/// Returns Visits event.
static EventType visits({Map<String, dynamic>? metadata}) =>
EventType("visits", metadata: metadata);

/// Returns Login event.
static EventType login({Map<String, dynamic>? metadata}) =>
EventType("login", metadata: metadata);

/// Returns signup event.
static EventType signup({Map<String, dynamic>? metadata}) =>
EventType("signup", metadata: metadata);

/// Returns Attach new device event.
static EventType attachNewDevice({Map<String, dynamic>? metadata}) =>
EventType("attach_new_device", metadata: metadata);

/// Returns Email change event.
static EventType emailChange({Map<String, dynamic>? metadata}) =>
EventType("emailChange", metadata: metadata);

/// Returns Profile update event.
static EventType profileUpdate({Map<String, dynamic>? metadata}) =>
EventType("profile_update", metadata: metadata);

/// Returns Password reset event.
static EventType passwordReset({Map<String, dynamic>? metadata}) =>
EventType("password_reset", metadata: metadata);

/// Returns Withdrawal event.
static EventType withdrawal({Map<String, dynamic>? metadata}) =>
EventType("withdrawal", metadata: metadata);

/// Returns Deposit event.
static EventType deposit({Map<String, dynamic>? metadata}) =>
EventType("deposit", metadata: metadata);

/// Returns Purchase event.
static EventType purchase({Map<String, dynamic>? metadata}) =>
EventType("purchase", metadata: metadata);

/// Returns Custom event.
static EventType custom(String name, {Map<String, dynamic>? metadata}) =>
EventType(name, metadata: metadata);
}
Loading

0 comments on commit de89d05

Please sign in to comment.