@chasexc/nativescript-fingerprint-auth
Version:
A fingerprint authentication plugin for use in NativeScript apps
255 lines (254 loc) • 11.8 kB
JavaScript
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;
;