@@ -15,8 +15,8 @@ export class FingerprintAuth implements FingerprintAuthApi {
1515
1616 constructor ( ) {
1717 this . keyguardManager = androidUtils
18- . getApplicationContext ( )
19- . getSystemService ( "keyguard" ) ;
18+ . getApplicationContext ( )
19+ . getSystemService ( "keyguard" ) ;
2020 }
2121
2222 // TODO can we detect face on the Samsung S8?
@@ -37,10 +37,10 @@ export class FingerprintAuth implements FingerprintAuthApi {
3737 }
3838
3939 const fingerprintManager = androidUtils
40- . getApplicationContext ( )
41- . getSystemService (
42- "fingerprint"
43- ) as android . hardware . fingerprint . FingerprintManager ;
40+ . getApplicationContext ( )
41+ . getSystemService (
42+ "fingerprint"
43+ ) as android . hardware . fingerprint . FingerprintManager ;
4444
4545 if ( ! fingerprintManager . isHardwareDetected ( ) ) {
4646 // Device doesn't support fingerprint authentication
@@ -59,7 +59,7 @@ export class FingerprintAuth implements FingerprintAuthApi {
5959 } else {
6060 // User hasn't enrolled any fingerprints to authenticate with
6161 reject (
62- `User hasn't enrolled any fingerprints to authenticate with`
62+ `User hasn't enrolled any fingerprints to authenticate with`
6363 ) ;
6464 }
6565 } else {
@@ -83,12 +83,11 @@ export class FingerprintAuth implements FingerprintAuthApi {
8383 } ) ;
8484 }
8585
86-
8786 private verifyWithCustomAndroidUI ( resolve , reject , authenticationCallback ) {
8887 // this instance is com.jesusm.kfingerprintmanager.KFingerprintManager, not the android OS fingerprint manager
8988 this . fingerPrintManager . authenticate (
90- authenticationCallback ,
91- this . getActivity ( ) . getSupportFragmentManager ( )
89+ authenticationCallback ,
90+ this . getActivity ( ) . getSupportFragmentManager ( )
9291 ) ;
9392 }
9493
@@ -98,73 +97,73 @@ export class FingerprintAuth implements FingerprintAuthApi {
9897 // in case 'activity.getSupportFragmentManager' is available ({N} started supporting it,
9998 // or the user added our Activity to their Android manifest), use the 3rd party FP library
10099 const hasSupportFragment =
101- this . getActivity ( ) . getSupportFragmentManager !== undefined ;
100+ this . getActivity ( ) . getSupportFragmentManager !== undefined ;
102101
103102 if ( options . useCustomAndroidUI && ! hasSupportFragment ) {
104103 reject ( {
105104 code : ERROR_CODES . DEVELOPER_ERROR ,
106105 message :
107- "Custom Fingerprint UI requires changes to AndroidManifest.xml. See the nativescript-fingerprint-auth documentation."
106+ "Custom Fingerprint UI requires changes to AndroidManifest.xml. See the nativescript-fingerprint-auth documentation."
108107 } ) ;
109108 } else if ( options . useCustomAndroidUI && hasSupportFragment ) {
110109 if ( ! this . fingerPrintManager ) {
111110 this . fingerPrintManager = new com . jesusm . kfingerprintmanager . KFingerprintManager (
112- androidUtils . getApplicationContext ( ) ,
113- KEY_NAME
111+ androidUtils . getApplicationContext ( ) ,
112+ KEY_NAME
114113 ) ;
115114 }
116115 const that = this ;
117116 const callback = new com . jesusm . kfingerprintmanager . KFingerprintManager . AuthenticationCallback (
118- {
119- attempts : 0 ,
120- onAuthenticationFailedWithHelp ( help ) : void {
121- if ( ++ this . attempts < 3 ) {
122- // just invoke the UI again as it's very sensitive (need a timeout to prevent an infinite loop)
123- setTimeout (
124- ( ) => that . verifyWithCustomAndroidUI ( resolve , reject , this ) ,
125- 50
126- ) ;
127- } else {
117+ {
118+ attempts : 0 ,
119+ onAuthenticationFailedWithHelp ( help ) : void {
120+ if ( ++ this . attempts < 3 ) {
121+ // just invoke the UI again as it's very sensitive (need a timeout to prevent an infinite loop)
122+ setTimeout (
123+ ( ) => that . verifyWithCustomAndroidUI ( resolve , reject , this ) ,
124+ 50
125+ ) ;
126+ } else {
127+ reject ( {
128+ code : ERROR_CODES . RECOVERABLE_ERROR ,
129+ message : help
130+ } ) ;
131+ }
132+ } ,
133+ onAuthenticationSuccess ( ) : void {
134+ resolve ( ) ;
135+ } ,
136+ onSuccessWithManualPassword ( password ) : void {
137+ resolve ( password ) ;
138+ } ,
139+ onFingerprintNotRecognized ( ) : void {
140+ if ( ++ this . attempts < 3 ) {
141+ // just invoke the UI again as it's very sensitive (need a timeout to prevent an infinite loop)
142+ setTimeout (
143+ ( ) => that . verifyWithCustomAndroidUI ( resolve , reject , this ) ,
144+ 50
145+ ) ;
146+ } else {
147+ reject ( {
148+ code : ERROR_CODES . NOT_RECOGNIZED ,
149+ message : "Fingerprint not recognized."
150+ } ) ;
151+ }
152+ } ,
153+ onFingerprintNotAvailable ( ) : void {
128154 reject ( {
129- code : ERROR_CODES . RECOVERABLE_ERROR ,
130- message : help
155+ code : ERROR_CODES . NOT_CONFIGURED ,
156+ message :
157+ 'Secure lock screen hasn\'t been set up.\n Go to "Settings -> Security -> Screenlock" to set up a lock screen.'
131158 } ) ;
132- }
133- } ,
134- onAuthenticationSuccess ( ) : void {
135- resolve ( ) ;
136- } ,
137- onSuccessWithManualPassword ( password ) : void {
138- resolve ( password ) ;
139- } ,
140- onFingerprintNotRecognized ( ) : void {
141- if ( ++ this . attempts < 3 ) {
142- // just invoke the UI again as it's very sensitive (need a timeout to prevent an infinite loop)
143- setTimeout (
144- ( ) => that . verifyWithCustomAndroidUI ( resolve , reject , this ) ,
145- 50
146- ) ;
147- } else {
159+ } ,
160+ onCancelled ( ) : void {
148161 reject ( {
149- code : ERROR_CODES . NOT_RECOGNIZED ,
150- message : "Fingerprint not recognized. "
162+ code : ERROR_CODES . PASSWORD_FALLBACK_SELECTED ,
163+ message : "Cancelled by user "
151164 } ) ;
152165 }
153- } ,
154- onFingerprintNotAvailable ( ) : void {
155- reject ( {
156- code : ERROR_CODES . NOT_CONFIGURED ,
157- message :
158- 'Secure lock screen hasn\'t been set up.\n Go to "Settings -> Security -> Screenlock" to set up a lock screen.'
159- } ) ;
160- } ,
161- onCancelled ( ) : void {
162- reject ( {
163- code : ERROR_CODES . PASSWORD_FALLBACK_SELECTED ,
164- message : "Cancelled by user"
165- } ) ;
166166 }
167- }
168167 ) ;
169168 this . verifyWithCustomAndroidUI ( resolve , reject , callback ) ;
170169 } else {
@@ -183,14 +182,14 @@ export class FingerprintAuth implements FingerprintAuthApi {
183182 }
184183 }
185184 app . android . off (
186- app . AndroidApplication . activityResultEvent ,
187- onActivityResult
185+ app . AndroidApplication . activityResultEvent ,
186+ onActivityResult
188187 ) ;
189188 } ;
190189
191190 app . android . on (
192- app . AndroidApplication . activityResultEvent ,
193- onActivityResult
191+ app . AndroidApplication . activityResultEvent ,
192+ onActivityResult
194193 ) ;
195194
196195 if ( ! this . keyguardManager ) {
@@ -200,13 +199,13 @@ export class FingerprintAuth implements FingerprintAuthApi {
200199 } ) ;
201200 }
202201 if (
203- this . keyguardManager &&
204- ! this . keyguardManager . isKeyguardSecure ( )
202+ this . keyguardManager &&
203+ ! this . keyguardManager . isKeyguardSecure ( )
205204 ) {
206205 reject ( {
207206 code : ERROR_CODES . NOT_CONFIGURED ,
208207 message :
209- 'Secure lock screen hasn\'t been set up.\n Go to "Settings -> Security -> Screenlock" to set up a lock screen.'
208+ 'Secure lock screen hasn\'t been set up.\n Go to "Settings -> Security -> Screenlock" to set up a lock screen.'
210209 } ) ;
211210 }
212211
@@ -235,11 +234,23 @@ export class FingerprintAuth implements FingerprintAuthApi {
235234 }
236235
237236 verifyFingerprintWithCustomFallback (
238- options : VerifyFingerprintWithCustomFallbackOptions
237+ options : VerifyFingerprintWithCustomFallbackOptions
239238 ) : Promise < any > {
240239 return this . verifyFingerprint ( options ) ;
241240 }
242241
242+ close ( ) : void {
243+ const fragmentManager = this . getActivity ( ) . getSupportFragmentManager ( ) ;
244+ // this is for custom ui
245+ const fragmentTag = "KFingerprintManager:fingerprintDialog" ;
246+ const fragment = fragmentManager . findFragmentByTag ( fragmentTag ) ;
247+ if ( fragment ) {
248+ fragmentManager . beginTransaction ( ) . remove ( fragment ) . commit ( ) ;
249+ } else {
250+ // AFAIK it's not possible to programmatically close the standard one
251+ }
252+ }
253+
243254 /**
244255 * Creates a symmetric key in the Android Key Store which can only be used after the user has
245256 * authenticated with device credentials within the last X seconds.
@@ -249,37 +260,37 @@ export class FingerprintAuth implements FingerprintAuthApi {
249260 const keyStore = java . security . KeyStore . getInstance ( "AndroidKeyStore" ) ;
250261 keyStore . load ( null ) ;
251262 const keyGenerator = javax . crypto . KeyGenerator . getInstance (
252- android . security . keystore . KeyProperties . KEY_ALGORITHM_AES ,
253- "AndroidKeyStore"
263+ android . security . keystore . KeyProperties . KEY_ALGORITHM_AES ,
264+ "AndroidKeyStore"
254265 ) ;
255266
256267 keyGenerator . init (
257- new android . security . keystore . KeyGenParameterSpec . Builder (
258- KEY_NAME ,
259- android . security . keystore . KeyProperties . PURPOSE_ENCRYPT |
260- android . security . keystore . KeyProperties . PURPOSE_DECRYPT
261- )
262- . setBlockModes ( [
263- android . security . keystore . KeyProperties . BLOCK_MODE_CBC
264- ] )
265- . setUserAuthenticationRequired ( true )
266- . setUserAuthenticationValidityDurationSeconds (
267- options && options . authenticationValidityDuration
268- ? options . authenticationValidityDuration
269- : 5
268+ new android . security . keystore . KeyGenParameterSpec . Builder (
269+ KEY_NAME ,
270+ android . security . keystore . KeyProperties . PURPOSE_ENCRYPT |
271+ android . security . keystore . KeyProperties . PURPOSE_DECRYPT
270272 )
271- . setEncryptionPaddings ( [
272- android . security . keystore . KeyProperties . ENCRYPTION_PADDING_PKCS7
273- ] )
274- . build ( )
273+ . setBlockModes ( [
274+ android . security . keystore . KeyProperties . BLOCK_MODE_CBC
275+ ] )
276+ . setUserAuthenticationRequired ( true )
277+ . setUserAuthenticationValidityDurationSeconds (
278+ options && options . authenticationValidityDuration
279+ ? options . authenticationValidityDuration
280+ : 5
281+ )
282+ . setEncryptionPaddings ( [
283+ android . security . keystore . KeyProperties . ENCRYPTION_PADDING_PKCS7
284+ ] )
285+ . build ( )
275286 ) ;
276287 keyGenerator . generateKey ( ) ;
277288 } catch ( error ) {
278289 // checks if the AES algorithm is implemented by the AndroidKeyStore
279290 if (
280- `${ error . nativeException } ` . indexOf (
281- "java.security.NoSuchAlgorithmException:"
282- ) > - 1
291+ `${ error . nativeException } ` . indexOf (
292+ "java.security.NoSuchAlgorithmException:"
293+ ) > - 1
283294 ) {
284295 // You need a device with API level >= 23 in order to detect if the user has already been authenticated in the last x seconds.
285296 }
@@ -293,9 +304,9 @@ export class FingerprintAuth implements FingerprintAuthApi {
293304 const secretKey = keyStore . getKey ( KEY_NAME , null ) ;
294305
295306 const cipher = javax . crypto . Cipher . getInstance (
296- `${ android . security . keystore . KeyProperties . KEY_ALGORITHM_AES } /${
297- android . security . keystore . KeyProperties . BLOCK_MODE_CBC
298- } /${ android . security . keystore . KeyProperties . ENCRYPTION_PADDING_PKCS7 } `
307+ `${ android . security . keystore . KeyProperties . KEY_ALGORITHM_AES } /${
308+ android . security . keystore . KeyProperties . BLOCK_MODE_CBC
309+ } /${ android . security . keystore . KeyProperties . ENCRYPTION_PADDING_PKCS7 } `
299310 ) ;
300311
301312 cipher . init ( javax . crypto . Cipher . ENCRYPT_MODE , secretKey ) ;
@@ -304,17 +315,17 @@ export class FingerprintAuth implements FingerprintAuthApi {
304315 return true ;
305316 } catch ( error ) {
306317 if (
307- `${ error . nativeException } ` . indexOf (
308- "android.security.keystore.UserNotAuthenticatedException"
309- ) > - 1
318+ `${ error . nativeException } ` . indexOf (
319+ "android.security.keystore.UserNotAuthenticatedException"
320+ ) > - 1
310321 ) {
311322 // the user must provide their credentials in order to proceed
312323 this . showAuthenticationScreen ( options ) ;
313324 return undefined ;
314325 } else if (
315- `${ error . nativeException } ` . indexOf (
316- "android.security.keystore.KeyPermanentlyInvalidatedException"
317- ) > - 1
326+ `${ error . nativeException } ` . indexOf (
327+ "android.security.keystore.KeyPermanentlyInvalidatedException"
328+ ) > - 1
318329 ) {
319330 // Invalid fingerprint
320331 console . log ( error ) ;
@@ -331,14 +342,14 @@ export class FingerprintAuth implements FingerprintAuthApi {
331342 private showAuthenticationScreen ( options ) : void {
332343 // https://developer.android.com/reference/android/app/KeyguardManager#createConfirmDeviceCredentialIntent(java.lang.CharSequence,%2520java.lang.CharSequence)
333344 const intent = ( this
334- . keyguardManager as any ) . createConfirmDeviceCredentialIntent (
335- options && options . title ? options . title : null ,
336- options && options . message ? options . message : null
345+ . keyguardManager as any ) . createConfirmDeviceCredentialIntent (
346+ options && options . title ? options . title : null ,
347+ options && options . message ? options . message : null
337348 ) ;
338349 if ( intent !== null ) {
339350 this . getActivity ( ) . startActivityForResult (
340- intent ,
341- REQUEST_CODE_CONFIRM_DEVICE_CREDENTIALS
351+ intent ,
352+ REQUEST_CODE_CONFIRM_DEVICE_CREDENTIALS
342353 ) ;
343354 }
344355 }
0 commit comments