Skip to content

Commit

Permalink
Merge branch 'feature/CXCDC-16405-biometric-support'
Browse files Browse the repository at this point in the history
  • Loading branch information
tal-mi committed Dec 20, 2023
2 parents 3e692a1 + ed9afe1 commit cdee575
Show file tree
Hide file tree
Showing 21 changed files with 855 additions and 52 deletions.
7 changes: 6 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
# 1.0.3
1.0.3

* Update Android core SDK.
* Added support for biometric session lock.

# 1.0.2
1.0.2

Expand All @@ -9,7 +15,6 @@
* Fixed nullable "apiVersion" bug on Android wrapper.
* Introduced Android proguard file.


# 1.0.1
1.0.1

Expand Down
5 changes: 3 additions & 2 deletions android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ android {
main.java.srcDirs += 'src/main/kotlin'
}
defaultConfig {
minSdkVersion 16
minSdkVersion 23
consumerProguardFiles 'lib-proguard-rules.txt'
}
lintOptions {
Expand All @@ -58,8 +58,9 @@ dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"

// Gigya SDK core implementation.
api 'com.sap.oss.gigya-android-sdk:sdk-core:7.0.7'
api 'com.sap.oss.gigya-android-sdk:sdk-core:7.0.8'
api 'com.github.SAP.gigya-android-sdk:sdk-auth:auth-v2.2.0'
api 'com.github.SAP.gigya-android-sdk:sdk-biometric:bio-v2.1.2'

api 'com.google.code.gson:gson:2.8.9'

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -93,12 +93,20 @@ class GigyaFlutterPlugin : FlutterPlugin, MethodCallHandler, ActivityAware, Scre
"otpLogin" -> sdk.otpLogin(call.arguments, result)
"otpUpdate" -> sdk.otpUpdate(call.arguments, result)
"otpVerify" -> sdk.otpVerify(call.arguments, result)
"biometricIsAvailable" -> sdk.biometricIsAvailable(result)
"biometricIsLocked" -> sdk.biometricIsLocked(result)
"biometricIsOptIn" -> sdk.biometricIsOptIn(result)
"biometricOptIn" -> sdk.biometricOptIn(call.arguments, result)
"biometricOptOut" -> sdk.biometricOptOut(call.arguments, result)
"biometricLockSession" -> sdk.biometricLockSession(result)
"biometricUnlockSession" -> sdk.biometricUnlockSession (call.arguments, result)
else -> result.notImplemented()
}
}

override fun onAttachedToActivity(binding: ActivityPluginBinding) {
val activity = binding.activity
sdk.setActivity(activity)
if (activity is ComponentActivity) {
fidoResultHandler = activity.registerForActivityResult(
ActivityResultContracts.StartIntentSenderForResult()
Expand All @@ -118,6 +126,7 @@ class GigyaFlutterPlugin : FlutterPlugin, MethodCallHandler, ActivityAware, Scre

override fun onDetachedFromActivity() {
fidoResultHandler = null
sdk.setActivity(null);
}

override fun addScreenSetEvent(event: Map<String, Any?>) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.sap.gigya_flutter_plugin

import android.app.Activity
import android.app.Application
import android.content.pm.PackageInfo
import android.content.pm.PackageManager
Expand All @@ -16,6 +17,9 @@ import com.gigya.android.sdk.auth.resolvers.IGigyaOtpResult
import com.gigya.android.sdk.containers.GigyaContainer
import com.gigya.android.sdk.interruption.IPendingRegistrationResolver
import com.gigya.android.sdk.interruption.link.ILinkAccountsResolver
import com.gigya.android.sdk.biometric.GigyaBiometric
import com.gigya.android.sdk.biometric.GigyaPromptInfo
import com.gigya.android.sdk.biometric.IGigyaBiometricCallback
import com.gigya.android.sdk.network.GigyaError
import com.gigya.android.sdk.session.SessionInfo
import com.gigya.android.sdk.ui.plugin.GigyaPluginEvent
Expand All @@ -29,20 +33,34 @@ import java.util.*

class GigyaSDKWrapper<T : GigyaAccount>(application: Application, accountObj: Class<T>) {
companion object {
/**
* General error code
*/
const val GENERAL_ERROR = "700"
const val GENERAL_ERROR_MESSAGE = "general error"
const val MISSING_PARAMETER_ERROR = "701"
const val MISSING_PARAMETER_MESSAGE = "request parameter missing"
/**
* Canceled error code
*/
const val CANCELED_ERROR = "702"
const val CANCELED_ERROR_MESSAGE = "Operation canceled"
/**
* Biometric error code
*/
const val BIOMETRIC_RECOGNITION_FAILED = "Fingerprint recognition failed"
}

private var sdk: Gigya<T>

private var sdkAuth: GigyaAuth

private var sdkBiometric: GigyaBiometric

private var resolverHelper: ResolverHelper = ResolverHelper()

private var activity: Activity? = null;

private val gson = GsonBuilder().registerTypeAdapter(
object : TypeToken<Map<String?, Any?>?>() {}.type,
CustomGSONDeserializer()
Expand All @@ -52,6 +70,7 @@ class GigyaSDKWrapper<T : GigyaAccount>(application: Application, accountObj: Cl
Gigya.setApplication(application)
sdk = Gigya.getInstance(accountObj)
sdkAuth = GigyaAuth.getInstance()
sdkBiometric = GigyaBiometric.getInstance()

try {
val pInfo: PackageInfo = getPackageInfo(application.packageManager, application.packageName)
Expand All @@ -63,6 +82,10 @@ class GigyaSDKWrapper<T : GigyaAccount>(application: Application, accountObj: Cl
}
}

fun setActivity(activity: Activity?) {
this.activity = activity;
}

@SuppressWarnings("deprecation")
private fun getPackageInfo(packageManager: PackageManager, packageName: String): PackageInfo {
if(Build.VERSION.SDK_INT < Build.VERSION_CODES.TIRAMISU){
Expand Down Expand Up @@ -1081,6 +1104,141 @@ class GigyaSDKWrapper<T : GigyaAccount>(application: Application, accountObj: Cl

//endregion

//region BIOMETRIC

fun biometricIsAvailable(channelResult: MethodChannel.Result) {
channelResult.success(sdkBiometric.isAvailable)
}

fun biometricIsLocked(channelResult: MethodChannel.Result) {
channelResult.success(sdkBiometric.isLocked)
}

fun biometricIsOptIn(channelResult: MethodChannel.Result) {
channelResult.success(sdkBiometric.isOptIn)
}

fun biometricOptIn(arguments: Any, channelResult: MethodChannel.Result) {
val argumentMap = arguments as Map<*, *>;
sdkBiometric.optIn(activity, GigyaPromptInfo(argumentMap["title"] as String?,
argumentMap["subtitle"] as String?,
argumentMap["description"] as String?),
object : IGigyaBiometricCallback {
override fun onBiometricOperationSuccess(action: GigyaBiometric.Action) {
channelResult.success(null)
}

override fun onBiometricOperationFailed(reason: String?) {
// TODO: Update to use error code once updated on Gigya Android SDK
if (reason != BIOMETRIC_RECOGNITION_FAILED) {
channelResult.error(
GENERAL_ERROR,
reason,
null
)
}
}

override fun onBiometricOperationCanceled() {
channelResult.error(
CANCELED_ERROR,
CANCELED_ERROR_MESSAGE,
null
)
}
})
}

fun biometricOptOut(arguments: Any, channelResult: MethodChannel.Result) {
val argumentMap = arguments as Map<*, *>;
sdkBiometric.optOut(activity, GigyaPromptInfo(argumentMap["title"] as String?,
argumentMap["subtitle"] as String?,
argumentMap["description"] as String?),
object : IGigyaBiometricCallback {
override fun onBiometricOperationSuccess(action: GigyaBiometric.Action) {
channelResult.success(null)
}

override fun onBiometricOperationFailed(reason: String?) {
// TODO: Update to use error code once updated on Gigya Android SDK
if (reason != BIOMETRIC_RECOGNITION_FAILED) {
channelResult.error(
GENERAL_ERROR,
reason,
null
)
}
}

override fun onBiometricOperationCanceled() {
channelResult.error(
CANCELED_ERROR,
CANCELED_ERROR_MESSAGE,
null
)
}
})
}

fun biometricLockSession(channelResult: MethodChannel.Result) {
sdkBiometric.lock(
object : IGigyaBiometricCallback {
override fun onBiometricOperationSuccess(action: GigyaBiometric.Action) {
channelResult.success(null)
}

override fun onBiometricOperationFailed(reason: String?) {
// TODO: Update to use error code once updated on Gigya Android SDK
if (reason != BIOMETRIC_RECOGNITION_FAILED) {
channelResult.error(
GENERAL_ERROR,
reason,
null
)
}
}

override fun onBiometricOperationCanceled() {
channelResult.error(
CANCELED_ERROR,
CANCELED_ERROR_MESSAGE,
null
)
}
})
}

fun biometricUnlockSession(arguments: Any, channelResult: MethodChannel.Result) {
val argumentMap = arguments as Map<*, *>;
sdkBiometric.unlock(activity, GigyaPromptInfo(argumentMap["title"] as String?,
argumentMap["subtitle"] as String?,
argumentMap["description"] as String?),
object : IGigyaBiometricCallback {
override fun onBiometricOperationSuccess(action: GigyaBiometric.Action) {
channelResult.success(null)
}

override fun onBiometricOperationFailed(reason: String?) {
// TODO: Update to use error code once updated on Gigya Android SDK
if (reason != BIOMETRIC_RECOGNITION_FAILED) {
channelResult.error(
GENERAL_ERROR,
reason,
null
)
}
}

override fun onBiometricOperationCanceled() {
channelResult.error(
CANCELED_ERROR,
CANCELED_ERROR_MESSAGE,
null
)
}
})
}

/**
* Map typed object to a Map<String, Any> object in order to pass on to
* the method channel response.
Expand Down
2 changes: 2 additions & 0 deletions example/android/app/src/debug/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,6 @@
to allow setting breakpoints, to provide hot reload, etc.
-->
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.USE_FINGERPRINT"/>
<uses-permission android:name="android.permission.USE_BIOMETRIC"/>
</manifest>

This file was deleted.

6 changes: 3 additions & 3 deletions example/lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import 'package:flutter/material.dart';
import 'package:gigya_flutter_plugin/gigya_flutter_plugin.dart';

import 'routes/account_information_page.dart';
import 'routes/biometrics_page.dart';
import 'routes/forgot_password_page.dart';
import 'routes/home_page.dart';
import 'routes/login_with_credentials_page.dart';
Expand All @@ -17,9 +18,7 @@ void main() async {

// Demonstrate explicit initialization before calling `runApp()`,
// using the configuration for the example app.

const String exampleAppApiKey =
'4_aOgBaARF4qkC9GnxcXCmdA';
const String exampleAppApiKey = '4_mL-YkAEegR9vzt6QvHWI5Q';
const String exampleAppApiDomain = 'us1.gigya.com';
const String exampleCname = 'YOUR-CNAME-HERE';

Expand Down Expand Up @@ -65,6 +64,7 @@ class _MyAppState extends State<MyApp> {
'/manage_connections': (_) => ManageConnectionsPage(sdk: widget.sdk),
'/forgot_password': (_) => ForgotPasswordPage(sdk: widget.sdk),
'/otp_phone_login': (_) => OneTimePasswordLoginPage(sdk: widget.sdk),
'/biometrics': (_) => BiometricsPage(sdk: widget.sdk),
},
);
}
Expand Down
Loading

0 comments on commit cdee575

Please sign in to comment.