UNPKG

@chasexc/nativescript-fingerprint-auth

Version:
255 lines (254 loc) 11.8 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.FingerprintAuth = void 0; var core_1 = require("@nativescript/core"); var utils_1 = require("@nativescript/core/utils"); var KEY_NAME = "fingerprintauth"; var SECRET_BYTE_ARRAY = Array.create("byte", 16); var REQUEST_CODE_CONFIRM_DEVICE_CREDENTIALS = 788; var FingerprintAuth = (function () { function FingerprintAuth() { this.keyguardManager = utils_1.ad .getApplicationContext() .getSystemService("keyguard"); } FingerprintAuth.prototype.available = function () { var _this = this; return new Promise(function (resolve, reject) { try { if (!_this.keyguardManager || !_this.keyguardManager.isKeyguardSecure()) { resolve({ any: false }); return; } if (android.os.Build.VERSION.SDK_INT < 23) { resolve({ any: false }); return; } var fingerprintManager = utils_1.ad .getApplicationContext() .getSystemService("fingerprint"); if (!fingerprintManager || !fingerprintManager.isHardwareDetected()) { resolve({ any: false }); } else { var configured = fingerprintManager.hasEnrolledFingerprints(); resolve({ any: true, touch: { supported: true, configured: configured } }); } } catch (ex) { console.log("fingerprint-auth.available: " + ex); reject(ex); } }); }; FingerprintAuth.prototype.didFingerprintDatabaseChange = function () { return new Promise(function (resolve, reject) { resolve(false); }); }; FingerprintAuth.prototype.verifyWithCustomAndroidUI = function (resolve, reject, authenticationCallback) { this.fingerPrintManager.authenticate(authenticationCallback, this.getActivity().getSupportFragmentManager()); }; FingerprintAuth.prototype.verifyFingerprint = function (options) { var _this = this; return new Promise(function (resolve, reject) { try { var hasSupportFragment = _this.getActivity().getSupportFragmentManager !== undefined; if (options.useCustomAndroidUI && !hasSupportFragment) { reject({ code: 10, message: "Custom Fingerprint UI requires changes to AndroidManifest.xml. See the nativescript-fingerprint-auth documentation." }); } else if (options.useCustomAndroidUI && hasSupportFragment) { if (!_this.fingerPrintManager) { _this.fingerPrintManager = new com.jesusm.kfingerprintmanager.KFingerprintManager(utils_1.ad.getApplicationContext(), KEY_NAME); } var that_1 = _this; var callback = new com.jesusm.kfingerprintmanager.KFingerprintManager.AuthenticationCallback({ attempts: 0, onAuthenticationFailedWithHelp: function (help) { var _this = this; if (++this.attempts < 3) { setTimeout(function () { return that_1.verifyWithCustomAndroidUI(resolve, reject, _this); }, 50); } else { reject({ code: 50, message: help }); } }, onAuthenticationSuccess: function () { resolve(); }, onSuccessWithManualPassword: function (password) { resolve(password); }, onFingerprintNotRecognized: function () { var _this = this; if (++this.attempts < 3) { setTimeout(function () { return that_1.verifyWithCustomAndroidUI(resolve, reject, _this); }, 50); } else { reject({ code: 40, message: "Fingerprint not recognized." }); } }, onFingerprintNotAvailable: function () { reject({ code: 30, message: 'Secure lock screen hasn\'t been set up.\n Go to "Settings -> Security -> Screenlock" to set up a lock screen.' }); }, onCancelled: function () { reject({ code: -3, message: "Cancelled by user" }); } }); _this.verifyWithCustomAndroidUI(resolve, reject, callback); } else { var onActivityResult_1 = function (data) { if (data.requestCode === REQUEST_CODE_CONFIRM_DEVICE_CREDENTIALS) { if (data.resultCode === android.app.Activity.RESULT_OK) { resolve(); } else { reject({ code: 60, message: "User cancelled." }); } } core_1.Application.android.off(core_1.AndroidApplication.activityResultEvent, onActivityResult_1); }; core_1.Application.android.on(core_1.AndroidApplication.activityResultEvent, onActivityResult_1); if (!_this.keyguardManager) { reject({ code: 20, message: "Keyguard manager not available." }); } if (_this.keyguardManager && !_this.keyguardManager.isKeyguardSecure()) { reject({ code: 30, message: 'Secure lock screen hasn\'t been set up.\n Go to "Settings -> Security -> Screenlock" to set up a lock screen.' }); } FingerprintAuth.createKey(options); var tryEncryptResult = _this.tryEncrypt(options); if (tryEncryptResult === undefined) { } else if (tryEncryptResult === true) { resolve(); } else { reject({ code: 70, message: "See the console for error logs." }); } } } catch (ex) { console.log("Error in fingerprint-auth.verifyFingerprint: " + ex); reject({ code: 70, message: ex }); } }); }; FingerprintAuth.prototype.verifyFingerprintWithCustomFallback = function (options) { return this.verifyFingerprint(options); }; FingerprintAuth.prototype.close = function () { var fragmentManager = this.getActivity().getSupportFragmentManager(); var fragmentTag = "KFingerprintManager:fingerprintDialog"; var fragment = fragmentManager.findFragmentByTag(fragmentTag); if (fragment) { fragmentManager.beginTransaction().remove(fragment).commit(); } else { } }; FingerprintAuth.createKey = function (options) { try { var keyStore = java.security.KeyStore.getInstance("AndroidKeyStore"); keyStore.load(null); var keyGenerator = javax.crypto.KeyGenerator.getInstance(android.security.keystore.KeyProperties.KEY_ALGORITHM_AES, "AndroidKeyStore"); keyGenerator.init(new android.security.keystore.KeyGenParameterSpec.Builder(KEY_NAME, android.security.keystore.KeyProperties.PURPOSE_ENCRYPT | android.security.keystore.KeyProperties.PURPOSE_DECRYPT) .setBlockModes([ android.security.keystore.KeyProperties.BLOCK_MODE_CBC ]) .setUserAuthenticationRequired(true) .setUserAuthenticationValidityDurationSeconds(options && options.authenticationValidityDuration ? options.authenticationValidityDuration : 5) .setEncryptionPaddings([ android.security.keystore.KeyProperties.ENCRYPTION_PADDING_PKCS7 ]) .build()); keyGenerator.generateKey(); } catch (error) { if (("" + error.nativeException).indexOf("java.security.NoSuchAlgorithmException:") > -1) { } } }; FingerprintAuth.prototype.tryEncrypt = function (options) { try { var keyStore = java.security.KeyStore.getInstance("AndroidKeyStore"); keyStore.load(null); var secretKey = keyStore.getKey(KEY_NAME, null); var cipher = javax.crypto.Cipher.getInstance(android.security.keystore.KeyProperties.KEY_ALGORITHM_AES + "/" + android.security.keystore.KeyProperties.BLOCK_MODE_CBC + "/" + android.security.keystore.KeyProperties.ENCRYPTION_PADDING_PKCS7); cipher.init(javax.crypto.Cipher.ENCRYPT_MODE, secretKey); cipher.doFinal(SECRET_BYTE_ARRAY); return true; } catch (error) { if (("" + error.nativeException).indexOf("android.security.keystore.UserNotAuthenticatedException") > -1) { this.showAuthenticationScreen(options); return undefined; } else if (("" + error.nativeException).indexOf("android.security.keystore.KeyPermanentlyInvalidatedException") > -1) { console.log(error); } else { console.log(error); } return false; } }; FingerprintAuth.prototype.showAuthenticationScreen = function (options) { var intent = this .keyguardManager.createConfirmDeviceCredentialIntent(options && options.title ? options.title : null, options && options.message ? options.message : null); if (intent !== null) { this.getActivity().startActivityForResult(intent, REQUEST_CODE_CONFIRM_DEVICE_CREDENTIALS); } }; FingerprintAuth.prototype.getActivity = function () { return core_1.Application.android.foregroundActivity || core_1.Application.android.startActivity; }; return FingerprintAuth; }()); exports.FingerprintAuth = FingerprintAuth;