diff --git a/src/ios/TouchID.h b/src/ios/TouchID.h index ddbc79f..3a462ea 100644 --- a/src/ios/TouchID.h +++ b/src/ios/TouchID.h @@ -35,5 +35,7 @@ - (void) verify:(CDVInvokedUrlCommand*)command; - (void) delete:(CDVInvokedUrlCommand*)command; - (void) setLocale:(CDVInvokedUrlCommand*)command; +- (void) didFingerprintDatabaseChange:(CDVInvokedUrlCommand*)command; + @end diff --git a/src/ios/TouchID.m b/src/ios/TouchID.m index 468a9fc..8fd6bce 100644 --- a/src/ios/TouchID.m +++ b/src/ios/TouchID.m @@ -22,6 +22,8 @@ Licensed to the Apache Software Foundation (ASF) under one #include #import +static NSString *const FingerprintDatabaseStateKey = @"FingerprintDatabaseStateKey"; + @implementation TouchID - (void)isAvailable:(CDVInvokedUrlCommand*)command{ @@ -166,4 +168,43 @@ -(void)verify:(CDVInvokedUrlCommand*)command{ [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId]; } } + +- (void) didFingerprintDatabaseChange:(CDVInvokedUrlCommand*)command { + // Get enrollment state + [self.commandDelegate runInBackground:^{ + LAContext *laContext = [[LAContext alloc] init]; + NSError *error = nil; + + // we expect the dev to have checked 'isAvailable' already so this should not return an error, + // we do however need to run canEvaluatePolicy here in order to get a non-nil evaluatedPolicyDomainState + if (![laContext canEvaluatePolicy:LAPolicyDeviceOwnerAuthenticationWithBiometrics error:&error]) { + [self.commandDelegate sendPluginResult:[CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:[error localizedDescription]] callbackId:command.callbackId]; + return; + } + + // only supported on iOS9+, so check this.. if not supported just report back as false + if (![laContext respondsToSelector:@selector(evaluatedPolicyDomainState)]) { + [self.commandDelegate sendPluginResult:[CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsBool:NO] callbackId:command.callbackId]; + return; + } + + NSData * state = [laContext evaluatedPolicyDomainState]; + if (state != nil) { + + NSString * stateStr = [state base64EncodedStringWithOptions:0]; + + NSString * storedState = [[NSUserDefaults standardUserDefaults] stringForKey:FingerprintDatabaseStateKey]; + + // whenever a finger is added/changed/removed the value of the storedState changes, + // so compare agains a value we previously stored in the context of this app + BOOL changed = storedState != nil && ![stateStr isEqualToString:storedState]; + + [self.commandDelegate sendPluginResult:[CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsBool:changed] callbackId:command.callbackId]; + + // Store enrollment + [[NSUserDefaults standardUserDefaults] setObject:stateStr forKey:FingerprintDatabaseStateKey]; + [[NSUserDefaults standardUserDefaults] synchronize]; + } + }]; +} @end diff --git a/www/touchid.js b/www/touchid.js index fb43320..97cbeaf 100644 --- a/www/touchid.js +++ b/www/touchid.js @@ -22,8 +22,10 @@ var touchid = { }, move: function(key, packageName,successCallback, errorCallback){ exec(successCallback, errorCallback, "TouchID", "move", [key,packageName]); - } - + }, + didFingerprintDatabaseChange: function (successCallback, errorCallback) { + exec(successCallback, errorCallback, "TouchID", "didFingerprintDatabaseChange", []); + } }; module.exports = touchid;