diff --git a/CHANGELOG.md b/CHANGELOG.md index 47c2dc6..fbdaca1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,13 @@ +## 1.8.0 + +- Updated iOS SDK + to [4.6.0-alpha04](https://github.com/Keyri-Co/keyri-ios-whitelabel-sdk/releases/tag/4.6.0-alpha04) +- Updated Android SDK + to [4.3.0-alpha05](https://github.com/Keyri-Co/keyri-android-whitelabel-sdk/releases/tag/4.3.0-alpha05) +- Fixed Keyri timestamps +- Added `getCorrectedTimestampSeconds` method which checks time changes and get corrected NTP + timestamp + ## 1.7.2 - Fixed `sendEvent` issue on Android diff --git a/android/build.gradle b/android/build.gradle index b32aa19..5fda6f2 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -48,8 +48,8 @@ android { dependencies { // Keyri - implementation 'com.keyri:keyrisdk:4.2.4' - implementation 'com.keyri:scanner:4.2.4' + implementation 'com.keyri:keyrisdk:4.3.0-alpha05' + implementation 'com.keyri:scanner:4.3.0-alpha05' // 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 58d52b3..3bd6ae3 100644 --- a/android/src/main/kotlin/com/keyrico/keyri/KeyriPlugin.kt +++ b/android/src/main/kotlin/com/keyrico/keyri/KeyriPlugin.kt @@ -54,8 +54,15 @@ class KeyriPlugin : FlutterPlugin, MethodCallHandler, ActivityAware, val appKey = arguments?.get("appKey") val publicApiKey = arguments?.get("publicApiKey") val serviceEncryptionKey = arguments?.get("serviceEncryptionKey") - val blockEmulatorDetection = - arguments?.get("blockEmulatorDetection")?.toBoolean() ?: true + val blockEmulatorDetection: Boolean = arguments?.get("blockEmulatorDetection")?.toBoolean() ?: true +// val blockRootDetection: Boolean = arguments?.get("blockRootDetection")?.toBoolean() ?: false +// val blockDangerousAppsDetection: Boolean = arguments?.get("blockDangerousAppsDetection")?.toBoolean() ?: false + + // TODO: Uncommnet when available +// val blockTamperDetection: Boolean = arguments?.get("blockTamperDetection")?.toBoolean() ?: true +// val blockTamperDetection: Boolean = true + +// val blockSwizzleDetection: Boolean = arguments?.get("blockSwizzleDetection")?.toBoolean() ?: false logMessage("Keyri: initialize called") initialize( @@ -63,6 +70,10 @@ class KeyriPlugin : FlutterPlugin, MethodCallHandler, ActivityAware, publicApiKey, serviceEncryptionKey, blockEmulatorDetection, +// blockRootDetection, +// blockDangerousAppsDetection, +// blockTamperDetection, +// blockSwizzleDetection result ) } @@ -164,6 +175,11 @@ class KeyriPlugin : FlutterPlugin, MethodCallHandler, ActivityAware, register(publicUserId, result) } + "getCorrectedTimestampSeconds" -> { + logMessage("Keyri: getCorrectedTimestampSeconds called") + getCorrectedTimestampSeconds(result) + } + "initializeDefaultConfirmationScreen" -> { logMessage("Keyri: initializeDefaultConfirmationScreen called") initializeDefaultConfirmationScreen(arguments?.get("payload"), result) @@ -227,6 +243,10 @@ class KeyriPlugin : FlutterPlugin, MethodCallHandler, ActivityAware, publicApiKey: String?, serviceEncryptionKey: String?, blockEmulatorDetection: Boolean, +// blockRootDetection: Boolean, +// blockDangerousAppsDetection: Boolean, +// blockTamperDetection: Boolean, +// blockSwizzleDetection: Boolean, result: MethodChannel.Result ) { if (appKey == null) { @@ -241,6 +261,14 @@ class KeyriPlugin : FlutterPlugin, MethodCallHandler, ActivityAware, publicApiKey, serviceEncryptionKey, blockEmulatorDetection + // TODO: Add impl +// KeyriDetectionsConfig( +// blockEmulatorDetection, +// false, +// false, +// true, +// false, +// ) ) } @@ -273,9 +301,11 @@ class KeyriPlugin : FlutterPlugin, MethodCallHandler, ActivityAware, appKey, publicApiKey, serviceEncryptionKey, - blockEmulatorDetection, + // TODO: Add impl +// blockEmulatorDetection, payload, - publicUserId + publicUserId, +// detectionsConfig = KeyriDetectionsConfig() ) easyKeyriAuthResult = result @@ -467,6 +497,15 @@ class KeyriPlugin : FlutterPlugin, MethodCallHandler, ActivityAware, } } + private fun getCorrectedTimestampSeconds(result: MethodChannel.Result) { + keyriCoroutineScope("getCorrectedTimestampSeconds", result::error).launch { + val correctedTimestampSeconds = keyri.getCorrectedTimestampSeconds() + + logMessage("Keyri getCorrectedTimestampSeconds: $correctedTimestampSeconds") + result.success(correctedTimestampSeconds) + } + } + private fun initializeDefaultConfirmationScreen( payload: String?, result: MethodChannel.Result diff --git a/example/ios/Runner.xcodeproj/project.pbxproj b/example/ios/Runner.xcodeproj/project.pbxproj index 8fba1d3..b62d533 100644 --- a/example/ios/Runner.xcodeproj/project.pbxproj +++ b/example/ios/Runner.xcodeproj/project.pbxproj @@ -138,6 +138,7 @@ 97C146EC1CF9000F007C117D /* Resources */, 9705A1C41CF9048500538489 /* Embed Frameworks */, 3B06AD1E1E4923F5004D2608 /* Thin Binary */, + 33A10266DE373D3FFFE9596F /* [CP] Copy Pods Resources */, ); buildRules = ( ); @@ -196,6 +197,23 @@ /* End PBXResourcesBuildPhase section */ /* Begin PBXShellScriptBuildPhase section */ + 33A10266DE373D3FFFE9596F /* [CP] Copy Pods Resources */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources-${CONFIGURATION}-input-files.xcfilelist", + ); + name = "[CP] Copy Pods Resources"; + outputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources-${CONFIGURATION}-output-files.xcfilelist", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources.sh\"\n"; + showEnvVarsInLog = 0; + }; 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { isa = PBXShellScriptBuildPhase; alwaysOutOfDate = 1; diff --git a/example/lib/main.dart b/example/lib/main.dart index 84cbcad..8d40d4b 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -94,6 +94,7 @@ class _KeyriHomePageState extends State { button(_sendEvent, 'Send event'), button(_login, 'Login'), button(_register, 'Register'), + button(_getCorrectedTimestampSeconds, 'Get timestamp'), button(_generateAssociationKey, 'Generate association key'), button(_getAssociationKey, 'Get association key'), button(_removeAssociationKey, 'Remove association key'), @@ -168,6 +169,23 @@ class _KeyriHomePageState extends State { .catchError((error, stackTrace) => _processError(error)); } + Future _getCorrectedTimestampSeconds() async { + Keyri? keyri = initKeyri(); + + if (keyri == null) return; + + String? publicUserId = usernameController.text; + + if (publicUserId.isEmpty) { + publicUserId = null; + } + + keyri + .getCorrectedTimestampSeconds() + .then((timestamp) => _showMessage('Timestamp: $timestamp')) + .catchError((error, stackTrace) => _processError(error)); + } + void _generateAssociationKey() { Keyri? keyri = initKeyri(); diff --git a/example/pubspec.yaml b/example/pubspec.yaml index 91ee67d..92ae3f2 100644 --- a/example/pubspec.yaml +++ b/example/pubspec.yaml @@ -1,5 +1,5 @@ name: keyri_example -version: 1.7.2 +version: 1.8.0 description: Demonstrates how to use the Keyri plugin. publish_to: 'none' diff --git a/ios/Classes/KeyriPlugin.m b/ios/Classes/KeyriPlugin.m index 2887801..2422b8e 100644 --- a/ios/Classes/KeyriPlugin.m +++ b/ios/Classes/KeyriPlugin.m @@ -53,6 +53,8 @@ - (void)handleMethodCall:(FlutterMethodCall*)call result:(FlutterResult)result { [self login:call result:result]; } else if ([@"register" isEqualToString:call.method]) { [self register:call result:result]; + } else if ([@"getCorrectedTimestampSeconds" isEqualToString:call.method]) { + [self getCorrectedTimestampSeconds:call result:result]; } else if ([@"initializeDefaultConfirmationScreen" isEqualToString:call.method]) { [self initializeDefaultConfirmationScreen:call result:result]; } else if ([@"processLink" isEqualToString:call.method]) { @@ -71,6 +73,11 @@ - (void)initialize:(FlutterMethodCall*)call result:(FlutterResult)result { id publicApiKeyValue = call.arguments[@"publicApiKey"]; id serviceEncryptionKeyValue = call.arguments[@"serviceEncryptionKey"]; id blockEmulatorDetectionValue = call.arguments[@"blockEmulatorDetection"]; + // TODO: Uncomment and add implementation +// id blockRootDetection = call.arguments[@"blockRootDetection"]; +// id blockDangerousAppsDetection = call.arguments[@"blockDangerousAppsDetection"]; +// id blockTamperDetection = call.arguments[@"blockTamperDetection"]; +// id blockSwizzleDetection = call.arguments[@"blockSwizzleDetection"]; if (appKey == nil || ![appKey isKindOfClass:[NSString class]]) { return [self sendErrorResult:result errorMessage:@"You need to provide appKey"]; @@ -85,6 +92,11 @@ - (void)initialize:(FlutterMethodCall*)call result:(FlutterResult)result { NSString *publicApiKey = [publicApiKeyValue isKindOfClass:[NSString class]] ? publicApiKeyValue : nil; NSString *serviceEncryptionKey = [serviceEncryptionKeyValue isKindOfClass:[NSString class]] ? serviceEncryptionKeyValue : nil; + // TODO: Add impl +// KeyriDetectionsConfig *config = [[KeyriDetectionsConfig alloc] initWithBlockEmulatorDetection: blockEmulatorDetection blockRootDetection:blockRootDetection blockDangerousAppsDetection:blockDangerousAppsDetection blockTamperDetection:blockTamperDetection blockSwizzleDetection:blockSwizzleDetection]; +// +// self.keyri = [[KeyriObjC alloc] initWithAppKey:appKey publicApiKey:publicApiKey serviceEncryptionKey:serviceEncryptionKey detectionsConfig:config]; + [self.keyri initializeKeyriWithAppKey:appKey publicApiKey:publicApiKey serviceEncryptionKey:serviceEncryptionKey blockEmulatorDetection:blockEmulatorDetection]; result(@(YES)); } @@ -296,6 +308,14 @@ - (void)register:(FlutterMethodCall*)call result:(FlutterResult)result { }]; } +- (void)getCorrectedTimestampSeconds:(FlutterMethodCall*)call result:(FlutterResult)result { + [self.keyri getCorrectedTimestampSecondsWithPubUserd:@"publicUserId" completion:^(double timestamp) { + NSInteger timeInSeconds = (NSInteger)ceil(timestamp); + + return result(@(timeInSeconds)); + }]; +} + - (void)initializeDefaultConfirmationScreen:(FlutterMethodCall*)call result:(FlutterResult)result { id payload = call.arguments[@"payload"]; diff --git a/ios/keyri_v3.podspec b/ios/keyri_v3.podspec index 39fa7dd..a26ea90 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.5.1' + spec.dependency 'keyri-pod', '~> 4.6.0-alpha04' # Flutter.framework does not contain a i386 slice. spec.pod_target_xcconfig = { 'DEFINES_MODULE' => 'YES', 'EXCLUDED_ARCHS[sdk=iphonesimulator*]' => 'i386' } diff --git a/lib/keyri.dart b/lib/keyri.dart index c706aa7..cc45037 100644 --- a/lib/keyri.dart +++ b/lib/keyri.dart @@ -111,6 +111,12 @@ class Keyri { return KeyriPlatform.instance.register(publicUserId); } + /// Call it to get timestamp synchronized with NTP. + /// Returns Future of [Long] object or error. + Future getCorrectedTimestampSeconds() { + return KeyriPlatform.instance.getCorrectedTimestampSeconds(); + } + /// Call it to show Confirmation screen with default UI. Future initializeDefaultConfirmationScreen(String payload) { return KeyriPlatform.instance.initializeDefaultConfirmationScreen(payload); diff --git a/lib/src/keyri_method_channel.dart b/lib/src/keyri_method_channel.dart index 5dc7bed..161506a 100644 --- a/lib/src/keyri_method_channel.dart +++ b/lib/src/keyri_method_channel.dart @@ -152,6 +152,11 @@ class MethodChannelKeyri extends KeyriPlatform { return RegisterObject.fromJson(registerObject); } + @override + Future getCorrectedTimestampSeconds() async { + return await methodChannel.invokeMethod('getCorrectedTimestampSeconds'); + } + @override Future initializeDefaultConfirmationScreen(String payload) async { return await methodChannel.invokeMethod( diff --git a/lib/src/keyri_platform_interface.dart b/lib/src/keyri_platform_interface.dart index 1125fe9..71ff80c 100644 --- a/lib/src/keyri_platform_interface.dart +++ b/lib/src/keyri_platform_interface.dart @@ -92,6 +92,10 @@ abstract class KeyriPlatform extends PlatformInterface { throw UnimplementedError('register() has not been implemented.'); } + Future getCorrectedTimestampSeconds() { + throw UnimplementedError('getCorrectedTimestampSeconds() has not been implemented.'); + } + Future initializeDefaultConfirmationScreen(String payload) { throw UnimplementedError( 'initializeDefaultConfirmationScreen() has not been implemented.'); diff --git a/pubspec.yaml b/pubspec.yaml index 0ca48f7..73e03c0 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: keyri_v3 description: Keyri QR Login plugin for Flutter. Provides Keyri SDK capabilities for secure and passwordless login. -version: 1.7.2 +version: 1.8.0 homepage: https://keyri.com environment: