Skip to content

Commit a512dec

Browse files
Android support, and rebranding to nativescript-fingerprint-auth because of it
1 parent 825b1f2 commit a512dec

File tree

6 files changed

+85
-101
lines changed

6 files changed

+85
-101
lines changed

README.md

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,29 @@
1-
# NativeScript Touch ID Plugin
2-
3-
Use the iOS fingerprint scanner in your {N} app.
1+
# NativeScript Fingerprint authentication Plugin
2+
Formerly known as `nativescript-fingerprint-auth`
43

54
<img src="images/fingerprint.png" />
65

76
### Use when
87
* You want to know if the device runing your app has enrolled for [Touch ID](https://support.apple.com/en-us/HT201371),
9-
* You want to leverage the TouchID sensor in your {N} app.
8+
* You want to leverage a fingerprint scanner in your {N} app.
109

1110
## Installation
1211
From the command prompt go to your app's root folder and execute:
1312
```
14-
tns plugin add nativescript-touchid
13+
tns plugin add nativescript-fingerprint-auth
1514
```
1615

1716
## Usage
1817

19-
If you want a quickstart, [clone our demo app](https://github.com/EddyVerbruggen/nativescript-touchid-demo).
18+
If you want a quickstart, [clone our demo app](https://github.com/EddyVerbruggen/nativescript-fingerprint-auth-demo).
2019

2120
Want a nicer guide than these raw code samples? Read [Nic Raboy's blog post about this plugin](https://www.thepolyglotdeveloper.com/2016/03/add-touch-id-authentication-support-to-your-nativescript-app/).
2221

2322
### function: available
2423
```js
25-
var touchid = require("nativescript-touchid");
24+
var fingerprintAuth = require("nativescript-fingerprint-auth");
2625

27-
touchid.available().then(
26+
fingerprintAuth.available().then(
2827
function(avail) {
2928
console.log("Available? " + avail);
3029
}
@@ -34,9 +33,10 @@ Want a nicer guide than these raw code samples? Read [Nic Raboy's blog post abou
3433
### function: verifyFingerprint
3534

3635
```js
37-
touchid.verifyFingerprint({
38-
message: 'Scan yer finger', // optional, shown in the fingerprint dialog (default on ios: 'Scan your finger', default on android: 'We are doing this for your own security.').
39-
title: 'Android title' // optional title for android,(default: 'Please confirm your credentials.')
36+
fingerprintAuth.verifyFingerprint({
37+
title: 'Android title', // optional title (used only on Android)
38+
message: 'Scan yer finger', // optional (used on both platforms)
39+
authenticationValidityDuration: 10 // optional (used on Android, default 0)
4040
}).then(
4141
function() {
4242
console.log("Fingerprint was OK");
@@ -52,7 +52,7 @@ Want a nicer guide than these raw code samples? Read [Nic Raboy's blog post abou
5252
#### Note: not implemented in android yet
5353

5454
```js
55-
touchid.verifyFingerprintWithCustomFallback({
55+
fingerprintAuth.verifyFingerprintWithCustomFallback({
5656
message: 'Scan yer finger', // optional, shown in the fingerprint dialog (default: 'Scan your finger').
5757
fallbackMessage: 'Enter PIN' // optional, the button label when scanning fails (default: 'Enter password').
5858
}).then(
@@ -77,10 +77,10 @@ before accepting valid fingerprints again.
7777
#### Note: not implemented in android yet
7878

7979
```js
80-
touchid.available().then(
80+
fingerprintAuth.available().then(
8181
function(avail) {
8282
if (avail) {
83-
touchid.didFingerprintDatabaseChange().then(
83+
fingerprintAuth.didFingerprintDatabaseChange().then(
8484
function(changed) {
8585
if (changed) {
8686
// re-auth the user by asking for his credentials before allowing a fingerprint scan again
@@ -95,6 +95,7 @@ touchid.available().then(
9595
```
9696

9797
## Changelog
98+
- 3.0.0 Android support added. Renamed `nativescript-touchid` to `nativescript-fingerprint-auth` (sorry for any inconvenience!)
9899
- 2.1.1 Xcode 8 compatibility - requires NativeScript 2.3.0+.
99100
- 2.1.0 Added `didFingerprintDatabaseChange` for enhanced security.
100101
- 2.0.0 Added `verifyFingerprintWithCustomFallback`, `verifyFingerprint` now falls back to the passcode.

touchid.android.js renamed to fingerprint-auth.android.js

Lines changed: 45 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -1,60 +1,45 @@
1-
21
var app = require('application');
32
var utils = require('utils/utils');
43

5-
var KeyguardManager = android.app.KeyguardManager;
6-
var ActivityCompat = android.support.v4.app.ActivityCompat;
7-
var Manifest = android.Manifest;
8-
var PackageManager = android.content.pm.PackageManager;
94
var KeyStore = java.security.KeyStore;
105
var Cipher = javax.crypto.Cipher;
116
var KeyGenerator = javax.crypto.KeyGenerator;
127
var KeyProperties = android.security.keystore.KeyProperties;
13-
var SecretKey = javax.crypto.SecretKey;
148
var KeyGenParameterSpec = android.security.keystore.KeyGenParameterSpec;
159

16-
17-
//var FingerprintManager;
18-
19-
//var KEYGUARD_SYSTEM_SERVICE = "keyguard";
20-
var KEY_NAME = 'fingerprintscanner';
10+
var KEY_NAME = 'fingerprintauth';
2111
var SECRET_BYTE_ARRAY = Array.create('byte', 16);
2212
var REQUEST_CODE_CONFIRM_DEVICE_CREDENTIALS = 1;
23-
var AUTHENTICATION_DURATION = 15; // in seconds
2413

2514
var activity = null;
26-
2715
var keyguardManager = null;
2816

29-
var title = null;
30-
var message = null;
31-
3217
var available = function () {
3318
return new Promise(function (resolve, reject) {
3419

3520
keyguardManager = utils.ad.getApplicationContext().getSystemService("keyguard");
3621

37-
if (!keyguardManager.isKeyguardSecure()) {
38-
resolve(false);
39-
return;
22+
if (!keyguardManager.isKeyguardSecure()) {
23+
resolve(false);
24+
return;
4025
}
4126

42-
if (android.os.Build.VERSION.SDK_INT >= 23) { //23 == android.os.BUILD.M
43-
//Fingerprint API only available on from Android 6.0 (M)
44-
var fingerprintManager = utils.ad.getApplicationContext().getSystemService("fingerprint");
45-
if (!fingerprintManager.isHardwareDetected()) {
46-
// Device doesn't support fingerprint authentication
47-
reject('Device doesn\'t support fingerprint authentication');
48-
} else if (!fingerprintManager.hasEnrolledFingerprints()) {
49-
// User hasn't enrolled any fingerprints to authenticate with
50-
reject('User hasn\'t enrolled any fingerprints to authenticate with');
51-
} else {
52-
resolve(true);
53-
}
54-
}else{
55-
reject('Your api version don\'t support fingerprint auth');
27+
if (android.os.Build.VERSION.SDK_INT >= 23) { //23 == android.os.BUILD.M
28+
//Fingerprint API only available on from Android 6.0 (M)
29+
var fingerprintManager = utils.ad.getApplicationContext().getSystemService("fingerprint");
30+
if (!fingerprintManager.isHardwareDetected()) {
31+
// Device doesn't support fingerprint authentication
32+
reject('Device doesn\'t support fingerprint authentication');
33+
} else if (!fingerprintManager.hasEnrolledFingerprints()) {
34+
// User hasn't enrolled any fingerprints to authenticate with
35+
reject('User hasn\'t enrolled any fingerprints to authenticate with');
36+
} else {
37+
resolve(true);
5638
}
57-
39+
}else{
40+
reject('Your api version don\'t support fingerprint auth');
41+
}
42+
5843
resolve(true);
5944
});
6045
};
@@ -67,10 +52,6 @@ var didFingerprintDatabaseChange = function () {
6752

6853

6954
var verifyFingerprint = function (arg) {
70-
if(arg){
71-
if(arg.title) title = arg.title;
72-
if(arg.message) message = arg.message;
73-
}
7455
return new Promise(function (resolve, reject) {
7556
activity = app.android.foregroundActivity;
7657
try {
@@ -86,16 +67,19 @@ var verifyFingerprint = function (arg) {
8667
}
8768
};
8869

89-
if (keyguardManager == null) {
70+
if (keyguardManager === null) {
9071
reject('Sorry, your device does not support keyguardManager.');
9172
}
9273
if (keyguardManager && !keyguardManager.isKeyguardSecure()) {
9374
reject('Secure lock screen hasn\'t been set up.\n Go to "Settings -> Security -> Screenlock" to set up a lock screen.');
9475
}
9576

96-
createKey();
97-
tryEncrypt();
98-
77+
createKey(arg);
78+
79+
if (tryEncrypt(arg)) {
80+
resolve(true);
81+
}
82+
9983
} catch (ex) {
10084
console.log("Error in verifyFingerprint: " + ex);
10185
reject(ex);
@@ -119,77 +103,71 @@ var verifyFingerprintWithCustomFallback = function (arg) {
119103
* Creates a symmetric key in the Android Key Store which can only be used after the user has
120104
* authenticated with device credentials within the last X seconds.
121105
*/
122-
function createKey() {
106+
function createKey(arg) {
123107
try {
124108
var keyStore = KeyStore.getInstance('AndroidKeyStore');
125109
keyStore.load(null);
126110
var keyGenerator = KeyGenerator.getInstance(KeyProperties.KEY_ALGORITHM_AES, 'AndroidKeyStore');
127111

128112
keyGenerator.init(
129-
new KeyGenParameterSpec.Builder(KEY_NAME, KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT)
130-
.setBlockModes([KeyProperties.BLOCK_MODE_CBC])
131-
.setUserAuthenticationRequired(true)
132-
.setUserAuthenticationValidityDurationSeconds(AUTHENTICATION_DURATION)
133-
.setEncryptionPaddings([KeyProperties.ENCRYPTION_PADDING_PKCS7])
134-
.build()
113+
new KeyGenParameterSpec.Builder(KEY_NAME, KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT)
114+
.setBlockModes([KeyProperties.BLOCK_MODE_CBC])
115+
.setUserAuthenticationRequired(true)
116+
.setUserAuthenticationValidityDurationSeconds(arg && arg.authenticationValidityDuration ? arg.authenticationValidityDuration : 0)
117+
.setEncryptionPaddings([KeyProperties.ENCRYPTION_PADDING_PKCS7])
118+
.build()
135119
);
136120
keyGenerator.generateKey();
137121
} catch (error) {
138122
// checks if the AES algorithm is implemented by the AndroidKeyStore
139123
if ((error.nativeException + '').indexOf('java.security.NoSuchAlgorithmException:') > -1) {
140-
//You need a device with API level >= 23 in order to detect if the user has already been authenticated in the last x seconds.
124+
//You need a device with API level >= 23 in order to detect if the user has already been authenticated in the last x seconds.
141125
}
142126
}
143127
}
144128

145-
146-
function tryEncrypt() {
129+
function tryEncrypt(arg) {
147130
try {
148131
var keyStore = KeyStore.getInstance('AndroidKeyStore');
149132
keyStore.load(null);
150133
var secretKey = keyStore.getKey(KEY_NAME, null);
151134

152135
var cipher = Cipher.getInstance(KeyProperties.KEY_ALGORITHM_AES + "/" +
153-
KeyProperties.BLOCK_MODE_CBC + "/" +
154-
KeyProperties.ENCRYPTION_PADDING_PKCS7);
136+
KeyProperties.BLOCK_MODE_CBC + "/" +
137+
KeyProperties.ENCRYPTION_PADDING_PKCS7);
155138

156139
cipher.init(Cipher.ENCRYPT_MODE, secretKey);
157140
cipher.doFinal(SECRET_BYTE_ARRAY);
158-
141+
159142
return true;
160143
} catch (error) {
161144
if ((error.nativeException + '').indexOf('android.security.keystore.UserNotAuthenticatedException') > -1) {
162145
// the user must provide their credentials in order to proceed
163-
showAuthenticationScreen();
146+
showAuthenticationScreen(arg);
164147
} else if((error.nativeException + '').indexOf('android.security.keystore.KeyPermanentlyInvalidatedException') > -1){
165148
//Invalid fingerprint
166149
console.log(error);
167150
} else {
168151
console.log(error);
169152
}
170-
171153
return false;
172154
}
173155
}
174156

175157
/**
176158
* Starts the built-in Android ConfirmDeviceCredential activity.
177159
*/
178-
function showAuthenticationScreen() {
179-
// title and description are optional, if you want the defaults,
180-
// you must pass nulls to the factory function
181-
182-
if(title === null) title = 'Please confirm your credentials.';
183-
if(message === null) message = 'We are doing this for your own security.';
184-
var intent = keyguardManager.createConfirmDeviceCredentialIntent(title, message);
185-
186-
if (intent != null) {
160+
function showAuthenticationScreen(arg) {
161+
var intent = keyguardManager.createConfirmDeviceCredentialIntent(
162+
arg && arg.title ? arg.title : null,
163+
arg && arg.message ? arg.message : null
164+
);
165+
if (intent !== null) {
187166
activity.startActivityForResult(intent, REQUEST_CODE_CONFIRM_DEVICE_CREDENTIALS);
188167
}
189168
}
190169

191170

192-
193171
exports.available = available;
194172
exports.didFingerprintDatabaseChange = didFingerprintDatabaseChange;
195173
exports.verifyFingerprint = verifyFingerprint;

touchid.d.ts renamed to fingerprint-auth.d.ts

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,17 @@
1-
declare module "nativescript-touchid" {
1+
declare module "nativescript-fingerprint-auth" {
22

33
export interface VerifyFingerprintOptions {
44
/**
5-
* The optional message in the fingerprint dialog on ios and page description on android.
6-
* Default: 'Scan your finger'.
5+
* The optional title in the fingerprint page for android.
6+
* Default: whatever the device default is ('Confirm your password' is likely)
77
*/
8-
message?: string;
8+
title?: string;
99

1010
/**
11-
* The optional title in the fingerprint page for android.
12-
* Default: 'We are doing this for your own security'.
11+
* The optional message in the fingerprint dialog on ios and page description on android.
12+
* Default: 'Scan your finger' on iOS and the device default on Android (which is likely 'Enter your device password to continue').
1313
*/
14-
15-
title?: string;
14+
message?: string;
1615
}
1716

1817
export interface verifyFingerprintWithCustomFallbackOptions {

touchid.ios.js renamed to fingerprint-auth.ios.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ var available = function () {
1010
LAContext.new().canEvaluatePolicyError(
1111
LAPolicyDeviceOwnerAuthenticationWithBiometrics, null));
1212
} catch (ex) {
13-
console.log("Error in touchid.available: " + ex);
13+
console.log("Error in fingerprint-auth.available: " + ex);
1414
resolve(false);
1515
}
1616
});
@@ -51,7 +51,7 @@ var didFingerprintDatabaseChange = function () {
5151
resolve(changed);
5252
}
5353
} catch (ex) {
54-
console.log("Error in touchid.didFingerprintDatabaseChange: " + ex);
54+
console.log("Error in fingerprint-auth.didFingerprintDatabaseChange: " + ex);
5555
resolve(false);
5656
}
5757
});
@@ -90,7 +90,7 @@ var verifyFingerprint = function (arg) {
9090
}
9191

9292
} catch (ex) {
93-
console.log("Error in touchid.verifyFingerprint: " + ex);
93+
console.log("Error in fingerprint-auth.verifyFingerprint: " + ex);
9494
reject(ex);
9595
}
9696
});
@@ -124,7 +124,7 @@ var verifyFingerprintWithCustomFallback = function (arg) {
124124
}
125125
);
126126
} catch (ex) {
127-
console.log("Error in touchid.verifyFingerprint: " + ex);
127+
console.log("Error in fingerprint-auth.verifyFingerprint: " + ex);
128128
reject(ex);
129129
}
130130
});

package.json

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
{
2-
"name": "nativescript-touchid",
3-
"version": "2.1.1",
4-
"description": "A TouchID (fingerprint scanner) module for use in NativeScript apps",
5-
"main": "touchid.js",
2+
"name": "nativescript-fingerprint-auth",
3+
"version": "3.0.0",
4+
"description": "A fingerprint authentication plugin for use in NativeScript apps",
5+
"main": "fingerprint-auth.js",
66
"nativescript": {
77
"platforms": {
88
"android": "2.3.0",
@@ -11,11 +11,13 @@
1111
},
1212
"repository": {
1313
"type": "git",
14-
"url": "https://github.com/eddyverbruggen/nativescript-touchid.git"
14+
"url": "https://github.com/eddyverbruggen/nativescript-fingerprint-auth.git"
1515
},
1616
"keywords": [
1717
"NativeScript",
1818
"ecosystem:nativescript",
19+
"iOS",
20+
"Android",
1921
"TouchID",
2022
"Touch ID",
2123
"Fingerprint",
@@ -28,10 +30,10 @@
2830
},
2931
"license": {
3032
"type": "MIT",
31-
"url": "https://github.com/eddyverbruggen/nativescript-touchid/blob/master/LICENSE"
33+
"url": "https://github.com/eddyverbruggen/nativescript-fingerprint-auth/blob/master/LICENSE"
3234
},
3335
"bugs": {
34-
"url": "https://github.com/eddyverbruggen/nativescript-touchid/issues"
36+
"url": "https://github.com/eddyverbruggen/nativescript-fingerprint-auth/issues"
3537
},
36-
"homepage": "https://github.com/eddyverbruggen/nativescript-touchid"
38+
"homepage": "https://github.com/eddyverbruggen/nativescript-fingerprint-auth"
3739
}

0 commit comments

Comments
 (0)