Skip to content

Commit 3377f44

Browse files
author
Matthew Wheatley
committed
*added API to check for fingerprint authentication availability
*checking for availability before showing auth dialog *throwing authentication error if not available
1 parent 290ce57 commit 3377f44

File tree

5 files changed

+95
-33
lines changed

5 files changed

+95
-33
lines changed

README.md

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
#Installation
2-
`meteor add cordova:cordova-plugin-android-fingerprint-auth@0.0.1`
2+
`meteor add cordova:cordova-plugin-android-fingerprint-auth`
33

44
#Setup
55
Add preferences to mobile-config.js
@@ -15,14 +15,15 @@ buildToolsVersion "23.0.2"
1515
```
1616

1717
#API
18+
##FingerprintAuth.show
1819
```
1920
FingerprintAuth.show({
2021
clientId: "myAppName",
2122
clientSecret: "a_very_secret_encryption_key"
2223
}, successCallback, errorCallback);
2324
2425
/**
25-
* @return {withFingerprint:base64EncodedString, withPassword:String}
26+
* @return {withFingerprint:base64EncodedString, withPassword:boolean}
2627
*/
2728
function successCallback(result) {
2829
console.log("successCallback(): " + JSON.stringify(result));
@@ -34,9 +35,35 @@ function successCallback(result) {
3435
}
3536
3637
function errorCallback(error) {
37-
console.log("errorCallback(): " + error);
38+
console.log(error); // "Fingerprint authentication not available"
3839
}
3940
4041
```
4142
Opens a native dialog fragment to use the device hardware fingerprint scanner to authenticate against fingerprints
42-
registered for the device.
43+
registered for the device.
44+
45+
##FingerprintAuth.isAvailable
46+
```
47+
FingerprintAuth.isAvailable(isAvailableSuccess, isAvailableError);
48+
49+
/**
50+
* @return {
51+
* isAvailable:boolean,
52+
* isHardwareDetected:boolean,
53+
* hasEnrolledFingerprints:boolean
54+
* }
55+
*/
56+
function isAvailableSuccess(isAvailable) {
57+
console.log("FingerprintAuth available: " + JSON.stringify(isAvailable)); // { isAvailable: true }
58+
if (isAvailable) {
59+
FingerprintAuth.show({
60+
clientId: "myAppName",
61+
clientSecret: "a_very_secret_encryption_key"
62+
}, successCallback, errorCallback);
63+
}
64+
}
65+
66+
function isAvailableError(message) {
67+
console.log("isAvailableError(): " + message);
68+
}
69+
```

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "cordova-plugin-android-fingerprint-auth",
3-
"version": "0.0.1",
3+
"version": "0.0.2",
44
"description": "Cordova plugin to use Android fingerprint authentication API",
55
"cordova": {
66
"id": "cordova-plugin-android-fingerprint-auth",

plugin.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
<plugin xmlns="http://apache.org/cordova/ns/plugins/1.0"
33
xmlns:android="http://schemas.android.com/apk/res/android"
44
id="cordova-plugin-android-fingerprint-auth"
5-
version="0.0.1">
5+
version="0.0.2">
66
<name>FingerprintAuth</name>
77
<description>Cordova plugin to use Android fingerprint authentication API</description>
88
<license>Apache 2.0</license>

src/android/FingerprintAuth.java

Lines changed: 52 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ public class FingerprintAuth extends CordovaPlugin {
5050
public static KeyStore mKeyStore;
5151
public static KeyGenerator mKeyGenerator;
5252
public static Cipher mCipher;
53+
private FingerprintManager mFingerPrintManager;
5354

5455
public static CallbackContext mCallbackContext;
5556
public static PluginResult mPluginResult;
@@ -82,6 +83,9 @@ public void initialize(CordovaInterface cordova, CordovaWebView webView) {
8283
mKeyguardManager = cordova.getActivity().getSystemService(KeyguardManager.class);
8384
mPluginResult = new PluginResult(PluginResult.Status.NO_RESULT);
8485

86+
mFingerPrintManager = cordova.getActivity().getApplicationContext()
87+
.getSystemService(FingerprintManager.class);
88+
8589
try {
8690
mKeyGenerator = KeyGenerator.getInstance(
8791
KeyProperties.KEY_ALGORITHM_AES, ANDROID_KEY_STORE);
@@ -118,45 +122,66 @@ public boolean execute(final String action,
118122
JSONArray args,
119123
CallbackContext callbackContext) throws JSONException {
120124
mCallbackContext = callbackContext;
121-
Log.v(TAG, "FingerprintAuth action:" + action);
125+
Log.v(TAG, "FingerprintAuth action: " + action);
122126

123127
JSONObject arg_object = args.getJSONObject(0);
124-
mClientId = arg_object.getString("clientId");
125-
mClientSecret = arg_object.getString("clientSecret");
126128

127129
if (action.equals("authenticate")) {
128-
createKey();
129-
cordova.getActivity().runOnUiThread(new Runnable() {
130-
public void run() {
131-
// Set up the crypto object for later. The object will be authenticated by use
132-
// of the fingerprint.
133-
if (initCipher()) {
130+
mClientId = arg_object.getString("clientId");
131+
mClientSecret = arg_object.getString("clientSecret");
132+
if (isFingerprintAuthAvailable()) {
133+
createKey();
134+
cordova.getActivity().runOnUiThread(new Runnable() {
135+
public void run() {
136+
// Set up the crypto object for later. The object will be authenticated by use
137+
// of the fingerprint.
138+
if (initCipher()) {
134139

135-
mFragment = new FingerprintAuthenticationDialogFragment();
136-
mFragment.setCancelable(false);
137-
// Show the fingerprint dialog. The user has the option to use the fingerprint with
138-
// crypto, or you can fall back to using a server-side verified password.
139-
mFragment.setCryptoObject(new FingerprintManager.CryptoObject(mCipher));
140-
mFragment.show(cordova.getActivity().getFragmentManager(), DIALOG_FRAGMENT_TAG);
141-
} else {
142-
// This happens if the lock screen has been disabled or or a fingerprint got
143-
// enrolled. Thus show the dialog to authenticate with their password first
144-
// and ask the user if they want to authenticate with fingerprints in the
145-
// future
146-
mFragment.setCryptoObject(new FingerprintManager.CryptoObject(mCipher));
147-
mFragment.setStage(
148-
FingerprintAuthenticationDialogFragment.Stage.NEW_FINGERPRINT_ENROLLED);
149-
mFragment.show(cordova.getActivity().getFragmentManager(), DIALOG_FRAGMENT_TAG);
140+
mFragment = new FingerprintAuthenticationDialogFragment();
141+
mFragment.setCancelable(false);
142+
// Show the fingerprint dialog. The user has the option to use the fingerprint with
143+
// crypto, or you can fall back to using a server-side verified password.
144+
mFragment.setCryptoObject(new FingerprintManager.CryptoObject(mCipher));
145+
mFragment.show(cordova.getActivity().getFragmentManager(), DIALOG_FRAGMENT_TAG);
146+
} else {
147+
// This happens if the lock screen has been disabled or or a fingerprint got
148+
// enrolled. Thus show the dialog to authenticate with their password first
149+
// and ask the user if they want to authenticate with fingerprints in the
150+
// future
151+
mFragment.setCryptoObject(new FingerprintManager.CryptoObject(mCipher));
152+
mFragment.setStage(
153+
FingerprintAuthenticationDialogFragment.Stage.NEW_FINGERPRINT_ENROLLED);
154+
mFragment.show(cordova.getActivity().getFragmentManager(), DIALOG_FRAGMENT_TAG);
155+
}
150156
}
151-
}
152-
});
153-
mPluginResult.setKeepCallback(true);
157+
});
158+
mPluginResult.setKeepCallback(true);
159+
mCallbackContext.sendPluginResult(mPluginResult);
160+
161+
} else {
162+
mPluginResult = new PluginResult(PluginResult.Status.ERROR);
163+
mCallbackContext.error("Fingerprint authentication not available");
164+
mCallbackContext.sendPluginResult(mPluginResult);
165+
}
166+
return true;
167+
} else if (action.equals("availability")) {
168+
JSONObject resultJson = new JSONObject();
169+
resultJson.put("isAvailable", isFingerprintAuthAvailable());
170+
resultJson.put("isHardwareDetected", mFingerPrintManager.isHardwareDetected());
171+
resultJson.put("hasEnrolledFingerprints", mFingerPrintManager.hasEnrolledFingerprints())
172+
mPluginResult = new PluginResult(PluginResult.Status.OK);
173+
mCallbackContext.success(resultJson);
154174
mCallbackContext.sendPluginResult(mPluginResult);
155175
return true;
156176
}
157177
return false;
158178
}
159179

180+
private boolean isFingerprintAuthAvailable() {
181+
return mFingerPrintManager.isHardwareDetected()
182+
&& mFingerPrintManager.hasEnrolledFingerprints();
183+
}
184+
160185
/**
161186
* Initialize the {@link Cipher} instance with the created key in the {@link #createKey()}
162187
* method.

www/FingerprintAuth.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,5 +16,15 @@ FingerprintAuth.prototype.show = function (params, successCallback, errorCallbac
1616
);
1717
}
1818

19+
FingerprintAuth.prototype.isAvailable = function (successCallback, errorCallback) {
20+
cordova.exec(
21+
successCallback,
22+
errorCallback,
23+
"FingerprintAuth", // Java Class
24+
"availability", // action
25+
[{}]
26+
);
27+
}
28+
1929
FingerprintAuth = new FingerprintAuth();
2030
module.exports = FingerprintAuth;

0 commit comments

Comments
 (0)