diff --git a/app/src/main/java/com/swifttech/remit/jmecustomer/base/PrefKeys.java b/app/src/main/java/com/swifttech/remit/jmecustomer/base/PrefKeys.java index 3ec2c737..4de3c0e8 100644 --- a/app/src/main/java/com/swifttech/remit/jmecustomer/base/PrefKeys.java +++ b/app/src/main/java/com/swifttech/remit/jmecustomer/base/PrefKeys.java @@ -59,4 +59,13 @@ public class PrefKeys { public static String APP_USER_SECRET_KEY ="APP_USER_SECRET_KEY"; public static String APP_USER_ID_SECRET_KEY ="APP_USER_ID_KEY"; public static String APP_SECRET_KEY ="APP_SECRET_KEY"; + public static String PREF_LOGIN_CREDENTIALS_DATA_ENCRYPTED ="login_credentials_data_encrypted"; + public static String PREF_LOGIN_CREDENTIALS_INITIALIZATION_VECTOR ="login_credentials_initialization_vector"; + public static String PREF_PIN_DATA_ENCRYPTED ="pin_data_encrypted"; + public static String PREF_PIN_INITIALIZATION_VECTOR ="pin_initialization_vector"; + public static String PREF_DEFAULT_ENCRYPTED ="pin_default_encrypted"; + public static String PREF_DEFAULT_INITIALIZATION_VECTOR ="default_initialization_vector"; + public static String FINGER_PRINT_LOGIN_ENABLED ="enabled_finger_print_login"; + + } diff --git a/app/src/main/java/com/swifttech/remit/jmecustomer/base/PrivilegedGateway.java b/app/src/main/java/com/swifttech/remit/jmecustomer/base/PrivilegedGateway.java index 6d0925af..039e6f94 100644 --- a/app/src/main/java/com/swifttech/remit/jmecustomer/base/PrivilegedGateway.java +++ b/app/src/main/java/com/swifttech/remit/jmecustomer/base/PrivilegedGateway.java @@ -219,10 +219,6 @@ public abstract class PrivilegedGateway extends BaseGateway implements Privilege RemitApplication.getStorage().edit().putString(PrefKeys.APP_SECRET_KEY, encrypted).apply(); } - @Override - public boolean isFingerPrintAuthEnabled() { - return RemitApplication.getStorage().getBoolean(PrefKeys.APP_FINGER_PRINT_ENABLED, false); - } @Override public String getPersistedUserId() { @@ -243,10 +239,7 @@ public abstract class PrivilegedGateway extends BaseGateway implements Privilege return secretKey; } - @Override - public void turnOffFingerprintAuth(boolean action) { - RemitApplication.getStorage().edit().putBoolean(PrefKeys.APP_FINGER_PRINT_ENABLED, !action).apply(); - } + @Override public void flushBiometricData() { @@ -267,4 +260,22 @@ public abstract class PrivilegedGateway extends BaseGateway implements Privilege public String getUserMsisdn() { return RemitApplication.getStorage().getString(PrefKeys.USER_MSISDN, ""); } + @Override + public boolean isFingerPrintAuthEnabled() { + return RemitApplication.getStorage().getBoolean(PrefKeys.APP_FINGER_PRINT_ENABLED, false); + } + @Override + public boolean isFingerPrintLoginEnabled() { + return RemitApplication.getStorage().getBoolean(PrefKeys.FINGER_PRINT_LOGIN_ENABLED, false); + } + @Override + public void turnOffFingerprintAuth(boolean action) { + RemitApplication.getStorage().edit().putBoolean(PrefKeys.APP_FINGER_PRINT_ENABLED, !action).apply(); + } + + @Override + public void turnOffFingerPrintLogin(boolean action) { + RemitApplication.getStorage().edit().putBoolean(PrefKeys.FINGER_PRINT_LOGIN_ENABLED, !action).apply(); + } + } diff --git a/app/src/main/java/com/swifttech/remit/jmecustomer/base/PrivilegedGatewayInterface.java b/app/src/main/java/com/swifttech/remit/jmecustomer/base/PrivilegedGatewayInterface.java index fb67ea3f..d864e664 100644 --- a/app/src/main/java/com/swifttech/remit/jmecustomer/base/PrivilegedGatewayInterface.java +++ b/app/src/main/java/com/swifttech/remit/jmecustomer/base/PrivilegedGatewayInterface.java @@ -91,7 +91,11 @@ public interface PrivilegedGatewayInterface extends BaseGatewayInterface { void turnOffFingerprintAuth(boolean action); + void turnOffFingerPrintLogin(boolean action); + void flushBiometricData(); String getCustomerRewardPoint(); + + boolean isFingerPrintLoginEnabled(); } diff --git a/app/src/main/java/com/swifttech/remit/jmecustomer/features/kyc/existingCustomer/presenter/ExistingKYCV3ViewModel.java b/app/src/main/java/com/swifttech/remit/jmecustomer/features/kyc/existingCustomer/presenter/ExistingKYCV3ViewModel.java index 60913480..4b57b9bb 100644 --- a/app/src/main/java/com/swifttech/remit/jmecustomer/features/kyc/existingCustomer/presenter/ExistingKYCV3ViewModel.java +++ b/app/src/main/java/com/swifttech/remit/jmecustomer/features/kyc/existingCustomer/presenter/ExistingKYCV3ViewModel.java @@ -43,6 +43,7 @@ import io.reactivex.schedulers.Schedulers; import io.reactivex.subjects.PublishSubject; import static android.app.Activity.RESULT_OK; +import static com.swifttech.remit.jmecustomer.utils.Constants.FINGER_PRINT; public class ExistingKYCV3ViewModel extends BaseViewModel implements ExistingKYCV3PresenterInterface { @@ -582,7 +583,10 @@ public class ExistingKYCV3ViewModel extends BaseViewModel implements ExistingKYC this.userPwd, appRelatedMetaData.getDeviceId(), Utils.getIPAddress(true), - fcmID) + fcmID, + false, + null, + null) .doOnSubscribe(sub -> view.showProgressBar(true, "")) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) diff --git a/app/src/main/java/com/swifttech/remit/jmecustomer/features/kyc/newCustomer/presenter/KYCV3ViewModel.java b/app/src/main/java/com/swifttech/remit/jmecustomer/features/kyc/newCustomer/presenter/KYCV3ViewModel.java index 73417b88..5b48cedd 100644 --- a/app/src/main/java/com/swifttech/remit/jmecustomer/features/kyc/newCustomer/presenter/KYCV3ViewModel.java +++ b/app/src/main/java/com/swifttech/remit/jmecustomer/features/kyc/newCustomer/presenter/KYCV3ViewModel.java @@ -797,7 +797,10 @@ public class KYCV3ViewModel extends BaseViewModel implements KYCV3PresenterInter this.userPwd, appRelatedMetaData.getDeviceId(), Utils.getIPAddress(true), - fcmID) + fcmID, + false, + null, + null) .doOnSubscribe(sub -> view.showProgressBar(true, "")) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) diff --git a/app/src/main/java/com/swifttech/remit/jmecustomer/features/login/gateway/LoginV2Gateway.java b/app/src/main/java/com/swifttech/remit/jmecustomer/features/login/gateway/LoginV2Gateway.java index 43d9eb0b..103813a7 100644 --- a/app/src/main/java/com/swifttech/remit/jmecustomer/features/login/gateway/LoginV2Gateway.java +++ b/app/src/main/java/com/swifttech/remit/jmecustomer/features/login/gateway/LoginV2Gateway.java @@ -24,7 +24,10 @@ public class LoginV2Gateway extends PrivilegedGateway implements LoginV2Interact String password, String uuid, String clientId, - String fcmId) { + String fcmId, + boolean IsBiometricLogin, + String fingerprintToken, + String BiometricLoginType) { JsonObject jsonObject = new JsonObject(); jsonObject.addProperty("accessCode", auth); jsonObject.addProperty("userId", userId); @@ -32,6 +35,9 @@ public class LoginV2Gateway extends PrivilegedGateway implements LoginV2Interact jsonObject.addProperty("uuid", uuid); jsonObject.addProperty("clientId", clientId); jsonObject.addProperty("fcmId", fcmId); + jsonObject.addProperty("IsBiometricLogin", IsBiometricLogin); + jsonObject.addProperty("fingerprintToken", fingerprintToken); + jsonObject.addProperty("BiometricLoginType", BiometricLoginType); return HttpClientV2.getInstance().signInV2(auth, jsonObject); } diff --git a/app/src/main/java/com/swifttech/remit/jmecustomer/features/login/presenter/LoginV2InteractorInterface.java b/app/src/main/java/com/swifttech/remit/jmecustomer/features/login/presenter/LoginV2InteractorInterface.java index 6ce1f4eb..4d431148 100644 --- a/app/src/main/java/com/swifttech/remit/jmecustomer/features/login/presenter/LoginV2InteractorInterface.java +++ b/app/src/main/java/com/swifttech/remit/jmecustomer/features/login/presenter/LoginV2InteractorInterface.java @@ -17,7 +17,10 @@ public interface LoginV2InteractorInterface extends BaseInteractorInterface { String password, String uuid, String clientId, - String fcmId); + String fcmId, + boolean isFingerPrintLogin, + String fingerprintToken, + String BiometricLoginType); Observable saveUserInfo(LoginModelV2 userRelatedData); diff --git a/app/src/main/java/com/swifttech/remit/jmecustomer/features/login/presenter/LoginV2PresenterInterface.java b/app/src/main/java/com/swifttech/remit/jmecustomer/features/login/presenter/LoginV2PresenterInterface.java index 28e1b686..20aa8f9e 100644 --- a/app/src/main/java/com/swifttech/remit/jmecustomer/features/login/presenter/LoginV2PresenterInterface.java +++ b/app/src/main/java/com/swifttech/remit/jmecustomer/features/login/presenter/LoginV2PresenterInterface.java @@ -8,7 +8,7 @@ import com.swifttech.remit.jmecustomer.base.BasePresenterInterface; public interface LoginV2PresenterInterface extends BasePresenterInterface { - void loginUser(); + void loginUser(boolean isBiometricLogin); LoginViewLiveData getLoginRelatedViewEvents(LoginViewLiveData.LoginViewBindings viewBindings); @@ -24,8 +24,12 @@ public interface LoginV2PresenterInterface extends BasePresenterInterface { void setNewToken(String newToken); + void setKeyStoreToken(String keyStoreToken); + boolean validateFormOnButtonClick(String userId,String Password); + boolean validateFormOnFingerPrintClick(String userId); + interface LoginV2ContractInterface extends BaseContractInterface { diff --git a/app/src/main/java/com/swifttech/remit/jmecustomer/features/login/presenter/LoginV2ViewModel.java b/app/src/main/java/com/swifttech/remit/jmecustomer/features/login/presenter/LoginV2ViewModel.java index 9c474f14..de3df256 100644 --- a/app/src/main/java/com/swifttech/remit/jmecustomer/features/login/presenter/LoginV2ViewModel.java +++ b/app/src/main/java/com/swifttech/remit/jmecustomer/features/login/presenter/LoginV2ViewModel.java @@ -24,6 +24,8 @@ import io.reactivex.disposables.Disposable; import io.reactivex.observers.DisposableObserver; import io.reactivex.schedulers.Schedulers; +import static com.swifttech.remit.jmecustomer.utils.Constants.FINGER_PRINT; + public class LoginV2ViewModel extends BaseViewModel implements LoginV2PresenterInterface, LoginV2InteractorInterface { @@ -36,6 +38,7 @@ public class LoginV2ViewModel extends BaseViewModel implements LoginV2PresenterI private final CompositeDisposable viewEventCompositeDisposable; private final RemitAuthManager remitAuthManager; private String newToken; + private String keyStoreToken; public LoginV2ViewModel(LoginV2ContractInterface view, LoginV2Gateway gateway) { @@ -50,7 +53,7 @@ public class LoginV2ViewModel extends BaseViewModel implements LoginV2PresenterI @Override - public void loginUser() { + public void loginUser(boolean isBiometricLogin) { RemitApplication.AppRelatedMetaData appRelatedMetaData = RemitApplication.getAppRelatedMetaData(view.getContext()); String fcmID = null; try { @@ -67,7 +70,11 @@ public class LoginV2ViewModel extends BaseViewModel implements LoginV2PresenterI loginValidator.password, appRelatedMetaData.getDeviceId(), Utils.getIPAddress(true), - fcmID) + fcmID, + isBiometricLogin, + keyStoreToken, + FINGER_PRINT + ) .doOnSubscribe(subs -> view.showProgressBar(true, "")) .subscribeOn(Schedulers.io()) .flatMap(loginResponse -> { @@ -84,6 +91,8 @@ public class LoginV2ViewModel extends BaseViewModel implements LoginV2PresenterI .subscribeWith(new LoginObserver())); } + + @Override public LoginViewLiveData getLoginRelatedViewEvents(LoginViewLiveData.LoginViewBindings viewBindings) { bindView(viewBindings); @@ -162,7 +171,6 @@ public class LoginV2ViewModel extends BaseViewModel implements LoginV2PresenterI @Override public void onRemitAuthSuccess(RemitAuthSuccessResult result) { loginValidator.password = result.getResult(); - loginUser(); } @Override @@ -188,6 +196,11 @@ public class LoginV2ViewModel extends BaseViewModel implements LoginV2PresenterI this.newToken = newToken; } + @Override + public void setKeyStoreToken(String keyStoreToken) { + this.keyStoreToken=keyStoreToken; + } + private void getLastLoginIfAvailable() { String userID = gateway.getUserID(); @@ -216,6 +229,15 @@ public class LoginV2ViewModel extends BaseViewModel implements LoginV2PresenterI } } + @Override + public boolean validateFormOnFingerPrintClick(String userId) { + if (loginValidator.validateUserId(userId) ) { + return true; + } else { + return false; + } + } + private class LoginValidator { diff --git a/app/src/main/java/com/swifttech/remit/jmecustomer/features/login/view/LoginV2Activity.java b/app/src/main/java/com/swifttech/remit/jmecustomer/features/login/view/LoginV2Activity.java index 3aa6871c..5f767750 100644 --- a/app/src/main/java/com/swifttech/remit/jmecustomer/features/login/view/LoginV2Activity.java +++ b/app/src/main/java/com/swifttech/remit/jmecustomer/features/login/view/LoginV2Activity.java @@ -33,22 +33,29 @@ import com.swifttech.remit.jmecustomer.base.PrefKeys; import com.swifttech.remit.jmecustomer.common.model.FormInputStateDTO; import com.swifttech.remit.jmecustomer.features.home.view.HomeActivityV2; import com.swifttech.remit.jmecustomer.features.login.LoginViewModelFactory; +import com.swifttech.remit.jmecustomer.features.login.gateway.LoginV2Gateway; import com.swifttech.remit.jmecustomer.features.login.presenter.LoginV2PresenterInterface; import com.swifttech.remit.jmecustomer.features.login.presenter.LoginV2ViewModel; import com.swifttech.remit.jmecustomer.features.login.presenter.LoginViewLiveData; import com.swifttech.remit.jmecustomer.features.registerv2.newcustomer.view.NewRegisterV2Activity; import com.swifttech.remit.jmecustomer.features.resetpassword.view.ResetPassV2Activity; +import com.swifttech.remit.jmecustomer.features.security.RemitAuthManager1; +import com.swifttech.remit.jmecustomer.features.security.model.RemitAuthFailedResult; +import com.swifttech.remit.jmecustomer.features.security.model.RemitAuthSuccessResult; +import java.nio.charset.StandardCharsets; import java.util.concurrent.Executor; import butterknife.BindView; import butterknife.ButterKnife; import static androidx.biometric.BiometricManager.Authenticators.BIOMETRIC_STRONG; +import static androidx.biometric.BiometricManager.Authenticators.BIOMETRIC_WEAK; import static androidx.biometric.BiometricManager.Authenticators.DEVICE_CREDENTIAL; +import static com.swifttech.remit.jmecustomer.utils.Constants.LOGIN; -public class LoginV2Activity extends BaseActivity implements View.OnClickListener, LoginV2PresenterInterface.LoginV2ContractInterface { +public class LoginV2Activity extends BaseActivity implements View.OnClickListener, LoginV2PresenterInterface.LoginV2ContractInterface, RemitAuthManager1.RemitAuthListener1 { public static final int KYC_REQUEST_FROM_LOGIN_SCREEN_CODE = 4281; public static final int KYC_REQUEST_FROM_LOGIN_SCREEN_CODE_LATER_PROCEED_TO_PENNY_TEST = 4282; @@ -88,6 +95,8 @@ public class LoginV2Activity extends BaseActivity implements View.OnClickListene private Executor executor; private BiometricPrompt biometricPrompt; private BiometricPrompt.PromptInfo promptInfo; + private RemitAuthManager1 remitAuthManager; + private LoginV2Gateway loginV2Gateway; @Override protected void onCreate(Bundle savedInstanceState) { @@ -98,9 +107,12 @@ public class LoginV2Activity extends BaseActivity implements View.OnClickListene initialize(); performDefaultAction(savedInstanceState); registerFcmToken(); - registerBiometric(); - - + loginV2Gateway=new LoginV2Gateway(); + //registerBiometric(); + remitAuthManager = new RemitAuthManager1(LoginV2Activity.this); + if (loginV2Gateway.isFingerPrintLoginEnabled()) { + fingerprintScannerTxtView.setVisibility(View.GONE); + } } private void registerBiometric() { @@ -264,7 +276,7 @@ public class LoginV2Activity extends BaseActivity implements View.OnClickListene case R.id.btn_submit: if (presenter.validateFormOnButtonClick(usernameId.getText().toString().trim(), passwordEdTxt.getText().toString().trim())) { - onLoginBtn(); + onLoginBtn(false); } break; @@ -279,9 +291,13 @@ public class LoginV2Activity extends BaseActivity implements View.OnClickListene break; case R.id.fingerprintScanner: - - BiometricManager biometricManager = BiometricManager.from(LoginV2Activity.this); - switch (biometricManager.canAuthenticate(BIOMETRIC_STRONG | DEVICE_CREDENTIAL)) { + try { + decryptLoginCredentialsWithBioMetric(LOGIN); + } catch (Exception e) { + e.printStackTrace(); + } + /*BiometricManager biometricManager = BiometricManager.from(LoginV2Activity.this); + switch (biometricManager.canAuthenticate(BIOMETRIC_WEAK)) { case BiometricManager.BIOMETRIC_SUCCESS: biometricPrompt.authenticate(promptInfo); break; @@ -291,19 +307,24 @@ public class LoginV2Activity extends BaseActivity implements View.OnClickListene BIOMETRIC_STRONG | DEVICE_CREDENTIAL); startActivityForResult(enrollIntent, BIOMETRIC_REQUEST_CODE); break; + + case BiometricManager.BIOMETRIC_ERROR_SECURITY_UPDATE_REQUIRED: + showToastMessage(getString(R.string.biometricSecurityUpdateRequired_text)); + break; + case BiometricManager.BIOMETRIC_ERROR_NO_HARDWARE: case BiometricManager.BIOMETRIC_ERROR_HW_UNAVAILABLE: default: showToastMessage(getString(R.string.deviceNotCompForBiometric)); break; - } + }*/ break; } } - private void onLoginBtn() { + private void onLoginBtn(boolean isBiometricLogin) { hideKeyBoard(); - presenter.loginUser(); + presenter.loginUser(isBiometricLogin); } @Override @@ -347,4 +368,31 @@ public class LoginV2Activity extends BaseActivity implements View.OnClickListene } + @Override + public void onRemitAuthSuccess(RemitAuthSuccessResult successResult, byte[] data) { + showToastMessage(successResult.getResult()); + setLoginRequest(data); + } + + private void setLoginRequest(byte[] data) { + String keyStoreToken= new String(data); + if (presenter.validateFormOnFingerPrintClick(usernameId.getText().toString().trim())) { + presenter.setKeyStoreToken(keyStoreToken); + onLoginBtn(true); + } + } + + @Override + public void onRemitAuthFailed(RemitAuthFailedResult failedResult) { + showToastMessage(failedResult.getFailedReason()); + } + + @Override + public void onRemitAuthCancelled() { + + } + + private void decryptLoginCredentialsWithBioMetric(String type) throws Exception { + remitAuthManager.decryptPrompt(type); + } } diff --git a/app/src/main/java/com/swifttech/remit/jmecustomer/features/register/presenter/RegisterV2Presenter.java b/app/src/main/java/com/swifttech/remit/jmecustomer/features/register/presenter/RegisterV2Presenter.java index 9c037a3b..594ca6e7 100644 --- a/app/src/main/java/com/swifttech/remit/jmecustomer/features/register/presenter/RegisterV2Presenter.java +++ b/app/src/main/java/com/swifttech/remit/jmecustomer/features/register/presenter/RegisterV2Presenter.java @@ -174,7 +174,10 @@ public class RegisterV2Presenter extends BaseViewModel implements RegisterV2Pres registerValidator.password, appRelatedMetaData.getDeviceId(), Utils.getIPAddress(true), - fcmID) + fcmID, + false, + null, + null) .subscribeOn(Schedulers.io()) .flatMap(loginResponse -> { if (loginResponse.getErrorCode().equalsIgnoreCase(Constants.SUCCESS_CODE_V2)) { diff --git a/app/src/main/java/com/swifttech/remit/jmecustomer/features/registerv2/existingcustomer/presenter/ExistingCustomerRegisterViewModel.java b/app/src/main/java/com/swifttech/remit/jmecustomer/features/registerv2/existingcustomer/presenter/ExistingCustomerRegisterViewModel.java index c56d0a6b..7f2a4eaa 100644 --- a/app/src/main/java/com/swifttech/remit/jmecustomer/features/registerv2/existingcustomer/presenter/ExistingCustomerRegisterViewModel.java +++ b/app/src/main/java/com/swifttech/remit/jmecustomer/features/registerv2/existingcustomer/presenter/ExistingCustomerRegisterViewModel.java @@ -266,7 +266,10 @@ public class ExistingCustomerRegisterViewModel extends BaseViewModel implements registerSubmitValidator.password, appRelatedMetaData.getDeviceId(), Utils.getIPAddress(true), - fcmID) + fcmID, + false, + null, + null) .subscribeOn(Schedulers.io()) .flatMap(loginResponse -> { if (loginResponse.getErrorCode().equalsIgnoreCase(Constants.SUCCESS_CODE_V2)) { diff --git a/app/src/main/java/com/swifttech/remit/jmecustomer/features/registerv2/newcustomer/presenter/NewRegisterV2Presenter.java b/app/src/main/java/com/swifttech/remit/jmecustomer/features/registerv2/newcustomer/presenter/NewRegisterV2Presenter.java index 554b21a1..acb0c020 100644 --- a/app/src/main/java/com/swifttech/remit/jmecustomer/features/registerv2/newcustomer/presenter/NewRegisterV2Presenter.java +++ b/app/src/main/java/com/swifttech/remit/jmecustomer/features/registerv2/newcustomer/presenter/NewRegisterV2Presenter.java @@ -133,7 +133,10 @@ public class NewRegisterV2Presenter extends BaseViewModel implements NewRegister registerValidator.password, appRelatedMetaData.getDeviceId(), Utils.getIPAddress(true), - fcmID + fcmID, + false, + null, + null ) .subscribeOn(Schedulers.io()) .flatMap(loginResponse -> { diff --git a/app/src/main/java/com/swifttech/remit/jmecustomer/features/security/RemitAuthManager.java b/app/src/main/java/com/swifttech/remit/jmecustomer/features/security/RemitAuthManager.java index 2ca4b7cb..b43ef51d 100644 --- a/app/src/main/java/com/swifttech/remit/jmecustomer/features/security/RemitAuthManager.java +++ b/app/src/main/java/com/swifttech/remit/jmecustomer/features/security/RemitAuthManager.java @@ -115,7 +115,7 @@ public class RemitAuthManager { public boolean isBiometricSupportedByDevice() { return false; //TODO disable biometric for now -// return RxFingerprint.isAvailable(context); +// return RxFingerprint.isAvailable(context); } public void turnOfBiometric(boolean action) { diff --git a/app/src/main/java/com/swifttech/remit/jmecustomer/features/security/RemitAuthManager1.java b/app/src/main/java/com/swifttech/remit/jmecustomer/features/security/RemitAuthManager1.java new file mode 100644 index 00000000..ae3f2225 --- /dev/null +++ b/app/src/main/java/com/swifttech/remit/jmecustomer/features/security/RemitAuthManager1.java @@ -0,0 +1,455 @@ +package com.swifttech.remit.jmecustomer.features.security; + +import android.content.SharedPreferences; +import android.os.Build; +import android.security.keystore.KeyGenParameterSpec; +import android.security.keystore.KeyProperties; +import android.util.Base64; + +import androidx.annotation.NonNull; +import androidx.annotation.RequiresApi; +import androidx.appcompat.app.AppCompatActivity; +import androidx.biometric.BiometricManager; +import androidx.biometric.BiometricPrompt; + +import com.swifttech.remit.jmecustomer.R; +import com.swifttech.remit.jmecustomer.RemitApplication; +import com.swifttech.remit.jmecustomer.features.security.model.RemitAuthFailedResult; +import com.swifttech.remit.jmecustomer.features.security.model.RemitAuthSuccessResult; + +import java.security.Key; +import java.security.KeyStore; +import java.util.Arrays; +import java.util.List; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; + +import javax.crypto.BadPaddingException; +import javax.crypto.Cipher; +import javax.crypto.IllegalBlockSizeException; +import javax.crypto.KeyGenerator; +import javax.crypto.SecretKey; +import javax.crypto.spec.IvParameterSpec; + +import static androidx.biometric.BiometricManager.Authenticators.BIOMETRIC_WEAK; +import static com.swifttech.remit.jmecustomer.base.PrefKeys.PREF_DEFAULT_ENCRYPTED; +import static com.swifttech.remit.jmecustomer.base.PrefKeys.PREF_DEFAULT_INITIALIZATION_VECTOR; +import static com.swifttech.remit.jmecustomer.base.PrefKeys.PREF_LOGIN_CREDENTIALS_DATA_ENCRYPTED; +import static com.swifttech.remit.jmecustomer.base.PrefKeys.PREF_LOGIN_CREDENTIALS_INITIALIZATION_VECTOR; +import static com.swifttech.remit.jmecustomer.base.PrefKeys.PREF_PIN_DATA_ENCRYPTED; +import static com.swifttech.remit.jmecustomer.base.PrefKeys.PREF_PIN_INITIALIZATION_VECTOR; +import static com.swifttech.remit.jmecustomer.utils.Constants.ACTION_DECRYPT; +import static com.swifttech.remit.jmecustomer.utils.Constants.ACTION_ENCRYPT; +import static com.swifttech.remit.jmecustomer.utils.Constants.ALGORITHM; +import static com.swifttech.remit.jmecustomer.utils.Constants.BIOMETRIC_ERROR_HW_UNAVAILABLE; +import static com.swifttech.remit.jmecustomer.utils.Constants.BIOMETRIC_ERROR_NONE_ENROLLED; +import static com.swifttech.remit.jmecustomer.utils.Constants.BIOMETRIC_ERROR_NO_HARDWARE; +import static com.swifttech.remit.jmecustomer.utils.Constants.BIOMETRIC_ERROR_SECURITY_UPDATE_REQUIRED; +import static com.swifttech.remit.jmecustomer.utils.Constants.BIOMETRIC_SUCCESS; +import static com.swifttech.remit.jmecustomer.utils.Constants.BLOCK_MODE; +import static com.swifttech.remit.jmecustomer.utils.Constants.DEFAULT; +import static com.swifttech.remit.jmecustomer.utils.Constants.KEYS_TORE; +import static com.swifttech.remit.jmecustomer.utils.Constants.KEY_DEFAULT_NAME; +import static com.swifttech.remit.jmecustomer.utils.Constants.KEY_LOGIN_CREDENTIALS_NAME; +import static com.swifttech.remit.jmecustomer.utils.Constants.KEY_PIN_NAME; +import static com.swifttech.remit.jmecustomer.utils.Constants.LOGIN; +import static com.swifttech.remit.jmecustomer.utils.Constants.PADDING; +import static com.swifttech.remit.jmecustomer.utils.Constants.PIN; +import static com.swifttech.remit.jmecustomer.utils.https.HTTPConstants.INVALID_REQUEST; + +public class RemitAuthManager1 { + private AppCompatActivity activity; + private RemitAuthListener1 listener; + private KeyStore keyStore; + + public RemitAuthManager1(AppCompatActivity activity) { + this.activity = activity; + } + + public void setListener(RemitAuthListener1 listener) { + this.listener = listener; + } + + private void resetParamToDefault() { + listener = null; + } + + @RequiresApi(Build.VERSION_CODES.M) + public SecretKey createKey(String type) throws Exception { + KeyGenerator keyGenerator = KeyGenerator.getInstance(KeyProperties.KEY_ALGORITHM_AES, KEYS_TORE); + String KEY_NAME; + switch (type) { + case PIN: + KEY_NAME = KEY_PIN_NAME; + break; + case LOGIN: + KEY_NAME = KEY_LOGIN_CREDENTIALS_NAME; + break; + default: + KEY_NAME = KEY_DEFAULT_NAME; + break; + } + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { + keyGenerator.init(new KeyGenParameterSpec.Builder(KEY_NAME, + KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT) + .setBlockModes(KeyProperties.BLOCK_MODE_CBC) + .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_PKCS7) + .setUserAuthenticationRequired(false) + .setInvalidatedByBiometricEnrollment(true) + .build()); + } else { + keyGenerator.init(new KeyGenParameterSpec.Builder(KEY_NAME, + KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT) + .setBlockModes(KeyProperties.BLOCK_MODE_CBC) + .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_PKCS7) + .setUserAuthenticationRequired(false) + .build()); + } + SecretKey secretKey = keyGenerator.generateKey(); + return secretKey; + } + + private Key getKey(String type) throws Exception { + keyStore = KeyStore.getInstance(KEYS_TORE); + keyStore.load(null); + switch (type) { + case PIN: + return keyStore.getKey(KEY_PIN_NAME, null); + case LOGIN: + return keyStore.getKey(KEY_LOGIN_CREDENTIALS_NAME, null); + default: + return keyStore.getKey(KEY_DEFAULT_NAME, null); + } + } + + void encryptPrompt( + String type, + byte[] data + ) throws Exception { + try { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + SecretKey secretKey = createKey(type); + Cipher cipher = getEncryptCipher(secretKey); + handleEncrypt(type, cipher, data); + + } + + } catch (Exception e) { + listener.onRemitAuthFailed(new RemitAuthFailedResult(activity.getResources().getString(R.string.unknownAuthReq_text) + "\n" + INVALID_REQUEST)); + } + } + + @RequiresApi(api = Build.VERSION_CODES.M) + private String combineAndReturnString() { + + List alphabets = Arrays.asList(ALGORITHM, BLOCK_MODE, PADDING); + String delimiter = "/"; + + String result = "", prefix = ""; + for (String s : alphabets) { + result += prefix + s; + prefix = delimiter; + } + return result; + } + + @RequiresApi(Build.VERSION_CODES.M) + private Cipher getEncryptCipher(Key key) throws Exception { + Cipher cipher = Cipher.getInstance(combineAndReturnString()); + cipher.init(Cipher.ENCRYPT_MODE, key); + return cipher; + } + + private void handleEncrypt( + String type, + Cipher cipher, + byte[] data + ) { + + ExecutorService executor = Executors.newSingleThreadExecutor(); + BiometricPrompt biometricPrompt = new BiometricPrompt(activity, + executor, new BiometricPrompt.AuthenticationCallback() { + @Override + public void onAuthenticationError(int errorCode, + @NonNull CharSequence errString) { + super.onAuthenticationError(errorCode, errString); + listener.onRemitAuthFailed(new RemitAuthFailedResult(activity.getResources().getString(R.string.unknownAuthReq_text) + "\n" + INVALID_REQUEST)); + } + + @Override + public void onAuthenticationSucceeded( + @NonNull BiometricPrompt.AuthenticationResult result) { + super.onAuthenticationSucceeded(result); + try { + Cipher resultCipher = result.getCryptoObject().getCipher(); + byte[] iv = resultCipher.getIV(); + byte[] encryptedData = resultCipher.doFinal(data); + saveEncryptedData(type, encryptedData, iv); + listener.onRemitAuthSuccess(new RemitAuthSuccessResult(activity.getString(R.string.fingerPrintEnrolledSucessfully_text)), encryptedData); + } catch (BadPaddingException e) { + e.printStackTrace(); + } catch (IllegalBlockSizeException e) { + e.printStackTrace(); + } + } + + @Override + public void onAuthenticationFailed() { + super.onAuthenticationFailed(); + listener.onRemitAuthFailed(new RemitAuthFailedResult(activity.getResources().getString(R.string.unknownAuthReq_text) + "\n" + INVALID_REQUEST)); + } + }); + BiometricPrompt.PromptInfo promptInfo = biometricPromptInfo(type, ACTION_ENCRYPT); + biometricPrompt.authenticate(promptInfo, new BiometricPrompt.CryptoObject(cipher)); + } + + private void saveEncryptedData( + String type, + byte[] dataEncrypted, + byte[] initializationVector + ) { + SharedPreferences.Editor sharedPreferenceEditor = RemitApplication.getStorage().edit(); + switch (type) { + case LOGIN: + sharedPreferenceEditor.putString(PREF_LOGIN_CREDENTIALS_DATA_ENCRYPTED, Base64.encodeToString( + dataEncrypted, + Base64.DEFAULT + )); + sharedPreferenceEditor.putString(PREF_LOGIN_CREDENTIALS_INITIALIZATION_VECTOR, Base64.encodeToString( + initializationVector, + Base64.DEFAULT + )); + break; + case PIN: + sharedPreferenceEditor.putString(PREF_PIN_DATA_ENCRYPTED, Base64.encodeToString( + dataEncrypted, + Base64.DEFAULT + )); + sharedPreferenceEditor.putString(PREF_PIN_INITIALIZATION_VECTOR, Base64.encodeToString( + initializationVector, + Base64.DEFAULT + )); + break; + default: + sharedPreferenceEditor.putString(PREF_DEFAULT_ENCRYPTED, Base64.encodeToString( + dataEncrypted, + Base64.DEFAULT + )); + sharedPreferenceEditor.putString(PREF_DEFAULT_INITIALIZATION_VECTOR, Base64.encodeToString( + initializationVector, + Base64.DEFAULT + )); + break; + + } + } + + public void decryptPrompt( + String type + ) throws Exception { + try { + Key secretKey = getKey(type); + byte[] initializationVector = getInitializationVector(type); + if (secretKey != null && initializationVector != null) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + Cipher cipher = getDecryptCipher(secretKey, initializationVector); + handleDecrypt(type, cipher); + } + } else { + listener.onRemitAuthFailed(new RemitAuthFailedResult(activity.getResources().getString(R.string.unknownAuthReq_text) + "\n" + INVALID_REQUEST)); + } + } catch (Exception e) { + listener.onRemitAuthFailed(new RemitAuthFailedResult(activity.getResources().getString(R.string.unknownAuthReq_text) + "\n" + INVALID_REQUEST)); + } + } + + private void handleDecrypt( + String type, + Cipher cipher + ) { + ExecutorService executor = Executors.newSingleThreadExecutor(); + BiometricPrompt biometricPrompt = new BiometricPrompt(activity, + executor, new BiometricPrompt.AuthenticationCallback() { + @Override + public void onAuthenticationError(int errorCode, + @NonNull CharSequence errString) { + super.onAuthenticationError(errorCode, errString); + listener.onRemitAuthFailed(new RemitAuthFailedResult(activity.getResources().getString(R.string.unknownAuthReq_text) + "\n" + INVALID_REQUEST)); + } + + @Override + public void onAuthenticationSucceeded( + @NonNull BiometricPrompt.AuthenticationResult result) { + super.onAuthenticationSucceeded(result); + try { + Cipher resultCipher = result.getCryptoObject().getCipher(); + byte[] encrypted = getEncryptedData(type); + byte[] data = resultCipher.doFinal(encrypted); + listener.onRemitAuthSuccess(new RemitAuthSuccessResult(activity.getString(R.string.fingerPrintEnrolledSucessfully_text)), data); + } catch (BadPaddingException e) { + e.printStackTrace(); + } catch (IllegalBlockSizeException e) { + e.printStackTrace(); + } + } + + @Override + public void onAuthenticationFailed() { + super.onAuthenticationFailed(); + listener.onRemitAuthFailed(new RemitAuthFailedResult(activity.getResources().getString(R.string.unknownAuthReq_text) + "\n" + INVALID_REQUEST)); + } + }); + BiometricPrompt.PromptInfo promptInfo = biometricPromptInfo(type, ACTION_DECRYPT); + biometricPrompt.authenticate(promptInfo, new BiometricPrompt.CryptoObject(cipher)); + } + + private byte[] getEncryptedData(String type) { + String iv = null; + switch (type) { + case PIN: + iv = RemitApplication.getStorage().getString(PREF_PIN_DATA_ENCRYPTED, null); + break; + case LOGIN: + iv = RemitApplication.getStorage().getString(PREF_LOGIN_CREDENTIALS_DATA_ENCRYPTED, null); + break; + default: + iv = RemitApplication.getStorage().getString(PREF_DEFAULT_ENCRYPTED, null); + break; + } + if (iv != null) { + return Base64.decode(iv, Base64.DEFAULT); + } else { + return null; + } + + } + + private byte[] getInitializationVector(String type) { + String iv = null; + switch (type) { + case PIN: + iv = RemitApplication.getStorage().getString(PREF_PIN_INITIALIZATION_VECTOR, null); + break; + case LOGIN: + iv = RemitApplication.getStorage().getString(PREF_LOGIN_CREDENTIALS_INITIALIZATION_VECTOR, null); + break; + default: + iv = RemitApplication.getStorage().getString(PREF_DEFAULT_INITIALIZATION_VECTOR, null); + break; + } + + if (iv != null) { + return Base64.decode(iv, Base64.DEFAULT); + } else { + return null; + } + } + + @RequiresApi(Build.VERSION_CODES.M) + private Cipher getDecryptCipher(Key key, byte[] iv) throws Exception { + Cipher cipher = Cipher.getInstance(combineAndReturnString()); + cipher.init(Cipher.ENCRYPT_MODE, key, new IvParameterSpec(iv)); + return cipher; + } + + public void updateCredential( + String type, + byte[] data + ) throws Exception { + try { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + Key secretKey = createKey(type); + Cipher cipher = getEncryptCipher(secretKey); + byte[] iv = cipher.getIV(); + byte[] encryptedData = cipher.doFinal(data); + saveEncryptedData(type, encryptedData, iv); + } + + } catch (Exception e) { + + } + } + + public void getUpdatedCredential(String type) throws Exception { + try { + Key secretKey = getKey(type); + byte[] initializationVector = getInitializationVector(type); + if (secretKey != null && initializationVector != null) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + Cipher cipher = getDecryptCipher(secretKey, initializationVector); + byte[] encrypted = getEncryptedData(type); + byte[] data = cipher.doFinal(encrypted); + } + } + } catch (Exception e) { + } + } + + private BiometricPrompt.PromptInfo biometricPromptInfo(String type, String actionType) { + String negativeButtonText = null; + switch (type) { + case LOGIN: + negativeButtonText = activity.getString(R.string.prompt_info_use_app_password); + break; + + case PIN: + negativeButtonText = activity.getString(R.string.label_use_pin); + break; + default: + negativeButtonText = DEFAULT; + break; + } + switch (actionType) { + case ACTION_ENCRYPT: + return new BiometricPrompt.PromptInfo.Builder() + .setTitle(activity.getString(R.string.app_name)) + .setDescription(activity.getString(R.string.biometric_prompt_description)) + .setConfirmationRequired(false) + .setNegativeButtonText(activity.getString(R.string.prompt_info_dismiss)) + .build(); + case ACTION_DECRYPT: + return new BiometricPrompt.PromptInfo.Builder() + .setTitle(activity.getString(R.string.app_name)) + .setDescription(activity.getString(R.string.biometric_prompt_description)) + .setNegativeButtonText(negativeButtonText.toUpperCase()) + .setConfirmationRequired(false) + .build(); + default: + return new BiometricPrompt.PromptInfo.Builder() + .setTitle(activity.getString(R.string.app_name)) + .setDescription(activity.getString(R.string.biometric_prompt_description)) + .setConfirmationRequired(false) + .build(); + } + } + + public String bioMetricCanAuthenticates() { + BiometricManager biometricManager = BiometricManager.from(activity); + switch (biometricManager.canAuthenticate(BIOMETRIC_WEAK)) { + case BiometricManager.BIOMETRIC_SUCCESS: + return BIOMETRIC_SUCCESS; + case BiometricManager.BIOMETRIC_ERROR_NONE_ENROLLED: + return BIOMETRIC_ERROR_NONE_ENROLLED; + + case BiometricManager.BIOMETRIC_ERROR_SECURITY_UPDATE_REQUIRED: + return BIOMETRIC_ERROR_SECURITY_UPDATE_REQUIRED; + + case BiometricManager.BIOMETRIC_ERROR_NO_HARDWARE: + return BIOMETRIC_ERROR_NO_HARDWARE; + + case BiometricManager.BIOMETRIC_ERROR_HW_UNAVAILABLE: + return BIOMETRIC_ERROR_HW_UNAVAILABLE; + default: + return null; + } + + } + + public interface RemitAuthListener1 { + void onRemitAuthSuccess(RemitAuthSuccessResult successResult, byte[] data); + + void onRemitAuthFailed(RemitAuthFailedResult failedResult); + + void onRemitAuthCancelled(); + } +} diff --git a/app/src/main/java/com/swifttech/remit/jmecustomer/features/settings/view/SettingsView.java b/app/src/main/java/com/swifttech/remit/jmecustomer/features/settings/view/SettingsView.java index f1ef0486..77b8f625 100644 --- a/app/src/main/java/com/swifttech/remit/jmecustomer/features/settings/view/SettingsView.java +++ b/app/src/main/java/com/swifttech/remit/jmecustomer/features/settings/view/SettingsView.java @@ -15,6 +15,7 @@ import com.swifttech.remit.jmecustomer.features.changepassword.view.UserPassword import com.swifttech.remit.jmecustomer.common.customwidgets.CustomAlertDialog; import com.swifttech.remit.jmecustomer.features.changetxnpin.view.ChangeTxnPinActivity; import com.swifttech.remit.jmecustomer.features.security.RemitAuthManager; +import com.swifttech.remit.jmecustomer.features.security.RemitAuthManager1; import com.swifttech.remit.jmecustomer.features.security.model.RemitAuthFailedResult; import com.swifttech.remit.jmecustomer.features.security.model.RemitAuthSuccessResult; import com.swifttech.remit.jmecustomer.features.settings.adapter.LanguageSelectionDialogRVAdapter; @@ -27,6 +28,8 @@ import butterknife.ButterKnife; import butterknife.OnClick; import io.reactivex.disposables.Disposable; +import static com.swifttech.remit.jmecustomer.utils.Constants.BIOMETRIC_ERROR_HW_UNAVAILABLE; +import static com.swifttech.remit.jmecustomer.utils.Constants.BIOMETRIC_ERROR_NO_HARDWARE; /** @@ -45,6 +48,7 @@ public class SettingsView extends BaseActivity implements CompoundButton.OnCheck LanguageSelectionGatewayInterface languageSelectionGatewayInterface; private RemitAuthManager remitAuthManager; + private RemitAuthManager1 remitAuthManager1; protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); @@ -55,6 +59,13 @@ public class SettingsView extends BaseActivity implements CompoundButton.OnCheck private void init() { ButterKnife.bind(this); remitAuthManager = RemitAuthManager.getGmeAuthManager(this); + remitAuthManager1=new RemitAuthManager1(this); + if(remitAuthManager1.bioMetricCanAuthenticates().equals(BIOMETRIC_ERROR_NO_HARDWARE) || remitAuthManager1.bioMetricCanAuthenticates().equals(BIOMETRIC_ERROR_HW_UNAVAILABLE)){ + view_fingerprint.setVisibility(View.GONE); + view_fingerprint_divider.setVisibility(View.GONE); + }else{ + + } languageSelectionGatewayInterface=new LanguageSelectionGateway(); if (!remitAuthManager.isBiometricSupportedByDevice()) { view_fingerprint.setVisibility(View.GONE); diff --git a/app/src/main/java/com/swifttech/remit/jmecustomer/utils/Constants.java b/app/src/main/java/com/swifttech/remit/jmecustomer/utils/Constants.java index 7093e935..62cdee20 100644 --- a/app/src/main/java/com/swifttech/remit/jmecustomer/utils/Constants.java +++ b/app/src/main/java/com/swifttech/remit/jmecustomer/utils/Constants.java @@ -1,5 +1,10 @@ package com.swifttech.remit.jmecustomer.utils; +import android.os.Build; +import android.security.keystore.KeyProperties; + +import androidx.annotation.RequiresApi; + /** * Created by frantic on 12/26/17. */ @@ -61,4 +66,34 @@ public class Constants { public static String PASSWORD_PATTERN="^(?=.*[A-Z])(?=.*[a-z])(?=.*[~!@+#.=$%^&*()_-\\{\\[\\}\\]\\?])(?=.*[0-9]).{8,24}$"; + + //FingerPrint + public static String KEYS_TORE = "AndroidKeyStore"; + public static String KEY_LOGIN_CREDENTIALS_NAME = "login_credentials_name"; + public static String KEY_PIN_NAME = "pin_store_key"; + public static String KEY_DEFAULT_NAME = "default_store_key"; + public static final String PIN = "PIN"; + public static final String LOGIN = "LOGIN"; + public static final String DEFAULT = "DEFAULT"; + + @RequiresApi(Build.VERSION_CODES.M) + public static final String ALGORITHM = KeyProperties.KEY_ALGORITHM_AES; + + @RequiresApi(Build.VERSION_CODES.M) + public static final String BLOCK_MODE = KeyProperties.BLOCK_MODE_CBC; + + @RequiresApi(Build.VERSION_CODES.M) + public static final String PADDING = KeyProperties.ENCRYPTION_PADDING_PKCS7; + + + public static final String ACTION_ENCRYPT = "ENCRYPT"; + public static final String ACTION_DECRYPT = "DECRYPT"; + + public static final String BIOMETRIC_SUCCESS = "BIOMETRIC_SUCCESS"; + public static final String BIOMETRIC_ERROR_NO_HARDWARE = "BIOMETRIC_ERROR_NO_HARDWARE"; + public static final String BIOMETRIC_ERROR_HW_UNAVAILABLE = "BIOMETRIC_ERROR_HW_UNAVAILABLE"; + public static final String BIOMETRIC_ERROR_NONE_ENROLLED = "BIOMETRIC_ERROR_NONE_ENROLLED"; + public static final String BIOMETRIC_ERROR_SECURITY_UPDATE_REQUIRED = "BIOMETRIC_ERROR_SECURITY_UPDATE_REQUIRED"; + public static final String FINGER_PRINT = "FINGER_PRINT"; + } diff --git a/app/src/main/java/com/swifttech/remit/jmecustomer/utils/Utils.java b/app/src/main/java/com/swifttech/remit/jmecustomer/utils/Utils.java index d78c36d1..2a0445d5 100644 --- a/app/src/main/java/com/swifttech/remit/jmecustomer/utils/Utils.java +++ b/app/src/main/java/com/swifttech/remit/jmecustomer/utils/Utils.java @@ -4,11 +4,11 @@ import android.content.Context; import android.content.pm.PackageManager; import android.graphics.Bitmap; import android.graphics.Color; -import android.net.wifi.WifiManager; import android.os.Build; import android.os.Environment; import android.provider.Settings; -import android.text.format.Formatter; +import android.security.keystore.KeyGenParameterSpec; +import android.security.keystore.KeyProperties; import android.util.Base64; import android.util.Log; import android.view.LayoutInflater; @@ -19,6 +19,7 @@ import android.view.animation.Transformation; import android.widget.ImageView; import android.widget.TextView; +import androidx.annotation.RequiresApi; import androidx.appcompat.app.AlertDialog; import androidx.core.content.ContextCompat; @@ -37,23 +38,39 @@ import java.io.File; import java.io.UnsupportedEncodingException; import java.net.InetAddress; import java.net.NetworkInterface; +import java.security.Key; +import java.security.KeyStore; import java.text.DecimalFormat; import java.text.NumberFormat; import java.text.ParseException; import java.text.SimpleDateFormat; +import java.util.Arrays; import java.util.Calendar; import java.util.Collections; import java.util.Date; -import java.util.Enumeration; import java.util.Hashtable; import java.util.List; import java.util.Locale; import java.util.regex.Matcher; import java.util.regex.Pattern; -import static android.content.Context.WIFI_SERVICE; +import javax.crypto.Cipher; +import javax.crypto.KeyGenerator; +import javax.crypto.SecretKey; + +import kotlin.Unit; + +import static com.swifttech.remit.jmecustomer.utils.Constants.ALGORITHM; +import static com.swifttech.remit.jmecustomer.utils.Constants.BLOCK_MODE; import static com.swifttech.remit.jmecustomer.utils.Constants.INTERNET; +import static com.swifttech.remit.jmecustomer.utils.Constants.KEYS_TORE; +import static com.swifttech.remit.jmecustomer.utils.Constants.KEY_DEFAULT_NAME; +import static com.swifttech.remit.jmecustomer.utils.Constants.KEY_LOGIN_CREDENTIALS_NAME; +import static com.swifttech.remit.jmecustomer.utils.Constants.KEY_PIN_NAME; +import static com.swifttech.remit.jmecustomer.utils.Constants.LOGIN; import static com.swifttech.remit.jmecustomer.utils.Constants.OTHER_ERROR; +import static com.swifttech.remit.jmecustomer.utils.Constants.PADDING; +import static com.swifttech.remit.jmecustomer.utils.Constants.PIN; import static com.swifttech.remit.jmecustomer.utils.Constants.SERVER_ERROR; /** @@ -63,6 +80,7 @@ import static com.swifttech.remit.jmecustomer.utils.Constants.SERVER_ERROR; public class Utils { + public final static boolean isValidEmail(CharSequence target) { if (target == null) { return false; @@ -76,8 +94,6 @@ public class Utils { } - - public static String toBase64(String message) { byte[] data; try { @@ -105,8 +121,6 @@ public class Utils { } - - public static String amountFormat(double amount) { String parsedAmount; try { @@ -118,7 +132,6 @@ public class Utils { } - //create bitmap from view and returns it public static File getOutputMediaFile() { @@ -204,7 +217,6 @@ public class Utils { } - /** * Returns the value before dot * @@ -239,8 +251,6 @@ public class Utils { } - - public static int getCurrentAPILevel() { return Build.VERSION.SDK_INT; } @@ -499,7 +509,6 @@ public class Utils { } - public static boolean isStringNotNullOrEmpty(String anotherIDType) { return (anotherIDType != null && anotherIDType.length() > 0); } @@ -543,10 +552,11 @@ public class Utils { } - public static void enableFcm(){ + public static void enableFcm() { FirebaseMessaging.getInstance().setAutoInitEnabled(true); } - public static void disableFCM(){ + + public static void disableFCM() { // Disable auto init FirebaseMessaging.getInstance().setAutoInitEnabled(false); new Thread(() -> { @@ -562,28 +572,31 @@ public class Utils { for (InetAddress addr : addrs) { if (!addr.isLoopbackAddress()) { String sAddr = addr.getHostAddress(); - boolean isIPv4 = sAddr.indexOf(':')<0; + boolean isIPv4 = sAddr.indexOf(':') < 0; if (useIPv4) { if (isIPv4) - Log.d("===>", "IPAddress 4: "+sAddr); - sAddr = sAddr.substring(sAddr.indexOf(":")+1); - return sAddr; + Log.d("===>", "IPAddress 4: " + sAddr); + sAddr = sAddr.substring(sAddr.indexOf(":") + 1); + return sAddr; } else { if (!isIPv4) { int delim = sAddr.indexOf('%'); // drop ip6 zone suffix - String ipv6Address=delim<0 ? sAddr.toUpperCase() : sAddr.substring(0, delim).toUpperCase(); + String ipv6Address = delim < 0 ? sAddr.toUpperCase() : sAddr.substring(0, delim).toUpperCase(); String substr = "::"; - ipv6Address = ipv6Address.substring(ipv6Address.indexOf(substr) + substr.length()); - Log.d("===>", " after IPAddress 6: "+ipv6Address); + ipv6Address = ipv6Address.substring(ipv6Address.indexOf(substr) + substr.length()); + Log.d("===>", " after IPAddress 6: " + ipv6Address); return ipv6Address; } } } } } - } catch (Exception ex) { } + } catch (Exception ex) { + } return ""; } + + } diff --git a/app/src/main/res/layout/fragment_existing_customer_registration_submit.xml b/app/src/main/res/layout/fragment_existing_customer_registration_submit.xml index 03943fa4..da0ba15a 100644 --- a/app/src/main/res/layout/fragment_existing_customer_registration_submit.xml +++ b/app/src/main/res/layout/fragment_existing_customer_registration_submit.xml @@ -70,7 +70,7 @@ app:errorTextAppearance="@style/MTextInpuLayoutErrorStyle" > @@ -89,7 +89,7 @@ app:errorTextAppearance="@style/MTextInpuLayoutErrorStyle" > @@ -101,7 +101,7 @@ android:id="@+id/newPin_TxtInputLayout" app:errorEnabled="true" style="@style/MTextInputLayoutForm" - app:endIconMode="password_toggle" + app:passwordToggleEnabled="true" android:maxLength="6" android:hint="@string/newPin_text" app:startIconDrawable="@drawable/icv_vd_lock" @@ -122,7 +122,7 @@ android:id="@+id/confirmPin_TxtInputLayout" app:errorEnabled="true" style="@style/MTextInputLayoutForm" - app:endIconMode="password_toggle" + app:passwordToggleEnabled="true" android:hint="@string/confirmPin_text" app:startIconDrawable="@drawable/icv_vd_lock" app:errorTextAppearance="@style/MTextInpuLayoutErrorStyle" diff --git a/app/src/main/res/values-bn/strings.xml b/app/src/main/res/values-bn/strings.xml index fce5a79f..6dd87b6e 100644 --- a/app/src/main/res/values-bn/strings.xml +++ b/app/src/main/res/values-bn/strings.xml @@ -544,4 +544,10 @@ Your Mobile is not compatiable for biometric login Change Password Please click here to change your Login Password + Biometric security update required + Fingerprint Enrolled Sucessfully + Use app password + Use PIN + Please put your finger on your fingerprint sensor in order to validate + Dismiss \ No newline at end of file diff --git a/app/src/main/res/values-ja/strings.xml b/app/src/main/res/values-ja/strings.xml index 8733e73c..e5449f52 100644 --- a/app/src/main/res/values-ja/strings.xml +++ b/app/src/main/res/values-ja/strings.xml @@ -544,5 +544,11 @@ Your Mobile is not compatiable for biometric login Change Password Please click here to change your Login Password + Biometric security update required + Fingerprint Enrolled Sucessfully + Use app password + Use PIN + Please put your finger on your fingerprint sensor in order to validate + Dismiss \ No newline at end of file diff --git a/app/src/main/res/values-ne/strings.xml b/app/src/main/res/values-ne/strings.xml index bedf250c..6472b593 100644 --- a/app/src/main/res/values-ne/strings.xml +++ b/app/src/main/res/values-ne/strings.xml @@ -543,4 +543,10 @@ Your Mobile is not compatiable for biometric login Change Password Please click here to change your Login Password + Biometric security update required + Fingerprint Enrolled Sucessfully + Use app password + Use PIN + Please put your finger on your fingerprint sensor in order to validate + Dismiss \ No newline at end of file diff --git a/app/src/main/res/values-vi/strings.xml b/app/src/main/res/values-vi/strings.xml index 812b1b29..b93081ab 100644 --- a/app/src/main/res/values-vi/strings.xml +++ b/app/src/main/res/values-vi/strings.xml @@ -540,5 +540,11 @@ Your Mobile is not compatiable for biometric login Change Password Please click here to change your Login Password + Biometric security update required + Fingerprint Enrolled Sucessfully + Use app password + Use PIN + Please put your finger on your fingerprint sensor in order to validate + Dismiss \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 388763e9..8c919d62 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -568,5 +568,11 @@ Membership ID Change Password Please click here to change your Login Password + Biometric security update required + Fingerprint Enrolled Sucessfully + Use app password + Use PIN + Please put your finger on your fingerprint sensor in order to validate + Dismiss