签约流程,指纹登录
authorqiaowei <jov123@163.com>
Fri, 27 Mar 2020 04:40:19 +0000 (12:40 +0800)
committerqiaowei <jov123@163.com>
Fri, 27 Mar 2020 04:40:19 +0000 (12:40 +0800)
165 files changed:
config.xml
package-lock.json
package.json
platforms/android/android.json
platforms/android/app/build.gradle
platforms/android/app/release/app-release.apk
platforms/android/app/src/main/AndroidManifest.xml
platforms/android/app/src/main/assets/www/cordova_plugins.js
platforms/android/app/src/main/assets/www/js/bindcard.js
platforms/android/app/src/main/assets/www/js/login.js
platforms/android/app/src/main/assets/www/js/main.js
platforms/android/app/src/main/assets/www/js/qrcode.js
platforms/android/app/src/main/assets/www/js/security.js
platforms/android/app/src/main/assets/www/js/server.js
platforms/android/app/src/main/assets/www/js/signxy.js
platforms/android/app/src/main/assets/www/main.html
platforms/android/app/src/main/assets/www/plugins/cordova-plugin-fingerprint-aio/www/Fingerprint.js
platforms/android/app/src/main/assets/www/qrcode.html
platforms/android/app/src/main/assets/www/security.html
platforms/android/app/src/main/assets/www/signxy.html
platforms/android/app/src/main/java/de/niklasmerz/cordova/biometric/BiometricActivity.java [new file with mode: 0644]
platforms/android/app/src/main/java/de/niklasmerz/cordova/biometric/Fingerprint.java [new file with mode: 0644]
platforms/android/app/src/main/java/de/niklasmerz/cordova/biometric/PluginError.java [new file with mode: 0644]
platforms/android/app/src/main/java/de/niklasmerz/cordova/biometric/PromptInfo.java [new file with mode: 0644]
platforms/android/app/src/main/java/de/niklasmerz/cordova/fingerprint/Fingerprint.java [deleted file]
platforms/android/app/src/main/java/de/niklasmerz/cordova/fingerprint/FingerprintAuthenticationDialogFragment.java [deleted file]
platforms/android/app/src/main/java/de/niklasmerz/cordova/fingerprint/FingerprintUiHelper.java [deleted file]
platforms/android/app/src/main/res/drawable-hdpi/ic_fp_40px.png [deleted file]
platforms/android/app/src/main/res/drawable-hdpi/icon.png
platforms/android/app/src/main/res/drawable-ldpi/icon.png
platforms/android/app/src/main/res/drawable-mdpi/ic_fp_40px.png [deleted file]
platforms/android/app/src/main/res/drawable-mdpi/icon.png
platforms/android/app/src/main/res/drawable-nodpi/android_robot.png [deleted file]
platforms/android/app/src/main/res/drawable-xhdpi/ic_fp_40px.png [deleted file]
platforms/android/app/src/main/res/drawable-xhdpi/icon.png
platforms/android/app/src/main/res/drawable-xxhdpi/ic_fp_40px.png [deleted file]
platforms/android/app/src/main/res/drawable-xxhdpi/icon.png
platforms/android/app/src/main/res/drawable-xxxhdpi/ic_fp_40px.png [deleted file]
platforms/android/app/src/main/res/drawable-xxxhdpi/icon.png
platforms/android/app/src/main/res/drawable/ic_fingerprint_error.xml [deleted file]
platforms/android/app/src/main/res/drawable/ic_fingerprint_success.xml [deleted file]
platforms/android/app/src/main/res/layout/biometric_activity.xml [new file with mode: 0644]
platforms/android/app/src/main/res/layout/fingerprint_dialog_container.xml [deleted file]
platforms/android/app/src/main/res/layout/fingerprint_dialog_content.xml [deleted file]
platforms/android/app/src/main/res/mipmap-hdpi-v26/ic_launcher_foreground.png
platforms/android/app/src/main/res/mipmap-hdpi/ic_launcher.png
platforms/android/app/src/main/res/mipmap-ldpi-v26/ic_launcher_foreground.png
platforms/android/app/src/main/res/mipmap-ldpi/ic_launcher.png
platforms/android/app/src/main/res/mipmap-mdpi-v26/ic_launcher_foreground.png
platforms/android/app/src/main/res/mipmap-mdpi/ic_launcher.png
platforms/android/app/src/main/res/mipmap-xhdpi-v26/ic_launcher_foreground.png
platforms/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png
platforms/android/app/src/main/res/mipmap-xxhdpi-v26/ic_launcher_foreground.png
platforms/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
platforms/android/app/src/main/res/mipmap-xxxhdpi-v26/ic_launcher_foreground.png
platforms/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
platforms/android/app/src/main/res/values-da/fpauth-strings.xml [deleted file]
platforms/android/app/src/main/res/values-de/fpauth-strings.xml [deleted file]
platforms/android/app/src/main/res/values-el/fpauth-strings.xml [deleted file]
platforms/android/app/src/main/res/values-es/fpauth-strings.xml [deleted file]
platforms/android/app/src/main/res/values-fr/fpauth-strings.xml [deleted file]
platforms/android/app/src/main/res/values-it/fpauth-strings.xml [deleted file]
platforms/android/app/src/main/res/values-nl/fpauth-strings.xml [deleted file]
platforms/android/app/src/main/res/values-pt/fpauth-strings.xml [deleted file]
platforms/android/app/src/main/res/values-zh-rTW/fpauth-strings.xml [deleted file]
platforms/android/app/src/main/res/values-zh/fpauth-strings.xml [deleted file]
platforms/android/app/src/main/res/values/biometric-styles.xml [new file with mode: 0644]
platforms/android/app/src/main/res/values/fpauth-colors.xml [deleted file]
platforms/android/app/src/main/res/values/fpauth-strings.xml [deleted file]
platforms/android/app/src/main/res/xml/config.xml
platforms/android/cordova-plugin-fingerprint-aio/app-build.gradle [new file with mode: 0644]
platforms/android/platform_www/cordova_plugins.js
platforms/android/platform_www/plugins/cordova-plugin-fingerprint-aio/www/Fingerprint.js
platforms/android/project.properties
platforms/browser/browser.json
platforms/browser/platform_www/cordova_plugins.js
platforms/browser/platform_www/plugins/cordova-plugin-fingerprint-aio/www/Fingerprint.js
platforms/ios/dlapp.xcodeproj/project.pbxproj
platforms/ios/dlapp/Images.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png
platforms/ios/dlapp/Images.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png
platforms/ios/dlapp/Images.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png
platforms/ios/dlapp/Images.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png
platforms/ios/dlapp/Images.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png
platforms/ios/dlapp/Images.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png
platforms/ios/dlapp/Images.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png
platforms/ios/dlapp/Images.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png
platforms/ios/dlapp/Images.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png
platforms/ios/dlapp/Images.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png
platforms/ios/dlapp/Images.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png
platforms/ios/dlapp/Images.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png
platforms/ios/dlapp/Images.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png
platforms/ios/dlapp/Images.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png
platforms/ios/dlapp/Images.xcassets/AppIcon.appiconset/ItunesArtwork@2x.png
platforms/ios/dlapp/Images.xcassets/iTunesArtwork@1x.png
platforms/ios/dlapp/Images.xcassets/iTunesArtwork@2x.png
platforms/ios/dlapp/Images.xcassets/iTunesArtwork@3x.png
platforms/ios/dlapp/Plugins/cordova-plugin-fingerprint-aio/Fingerprint.swift
platforms/ios/dlapp/config.xml
platforms/ios/ios.json
platforms/ios/platform_www/cordova_plugins.js
platforms/ios/platform_www/plugins/cordova-plugin-fingerprint-aio/www/Fingerprint.js
plugins/android.json
plugins/browser.json
plugins/cordova-plugin-fingerprint-aio/.travis.yml
plugins/cordova-plugin-fingerprint-aio/README.md
plugins/cordova-plugin-fingerprint-aio/package.json
plugins/cordova-plugin-fingerprint-aio/plugin.xml
plugins/cordova-plugin-fingerprint-aio/res/android/drawable-hdpi/ic_fp_40px.png [deleted file]
plugins/cordova-plugin-fingerprint-aio/res/android/drawable-mdpi/ic_fp_40px.png [deleted file]
plugins/cordova-plugin-fingerprint-aio/res/android/drawable-nodpi/android_robot.png [deleted file]
plugins/cordova-plugin-fingerprint-aio/res/android/drawable-xhdpi/ic_fp_40px.png [deleted file]
plugins/cordova-plugin-fingerprint-aio/res/android/drawable-xxhdpi/ic_fp_40px.png [deleted file]
plugins/cordova-plugin-fingerprint-aio/res/android/drawable-xxxhdpi/ic_fp_40px.png [deleted file]
plugins/cordova-plugin-fingerprint-aio/res/android/drawable/ic_fingerprint_error.xml [deleted file]
plugins/cordova-plugin-fingerprint-aio/res/android/drawable/ic_fingerprint_success.xml [deleted file]
plugins/cordova-plugin-fingerprint-aio/res/android/layout/fingerprint_dialog_container.xml [deleted file]
plugins/cordova-plugin-fingerprint-aio/res/android/layout/fingerprint_dialog_content.xml [deleted file]
plugins/cordova-plugin-fingerprint-aio/res/android/values-da/fpauth-strings.xml [deleted file]
plugins/cordova-plugin-fingerprint-aio/res/android/values-de/fpauth-strings.xml [deleted file]
plugins/cordova-plugin-fingerprint-aio/res/android/values-el/fpauth-strings.xml [deleted file]
plugins/cordova-plugin-fingerprint-aio/res/android/values-es/fpauth-strings.xml [deleted file]
plugins/cordova-plugin-fingerprint-aio/res/android/values-fr/fpauth-strings.xml [deleted file]
plugins/cordova-plugin-fingerprint-aio/res/android/values-it/fpauth-strings.xml [deleted file]
plugins/cordova-plugin-fingerprint-aio/res/android/values-nl/fpauth-strings.xml [deleted file]
plugins/cordova-plugin-fingerprint-aio/res/android/values-pt/fpauth-strings.xml [deleted file]
plugins/cordova-plugin-fingerprint-aio/res/android/values-zh-rTW/fpauth-strings.xml [deleted file]
plugins/cordova-plugin-fingerprint-aio/res/android/values-zh/fpauth-strings.xml [deleted file]
plugins/cordova-plugin-fingerprint-aio/res/android/values/fpauth-colors.xml [deleted file]
plugins/cordova-plugin-fingerprint-aio/res/android/values/fpauth-strings.xml [deleted file]
plugins/cordova-plugin-fingerprint-aio/src/android/.gradle/6.0-20191016123526+0000/fileChanges/last-build.bin [new file with mode: 0644]
plugins/cordova-plugin-fingerprint-aio/src/android/.gradle/6.0-20191016123526+0000/fileHashes/fileHashes.lock [new file with mode: 0644]
plugins/cordova-plugin-fingerprint-aio/src/android/.gradle/6.0-20191016123526+0000/gc.properties [new file with mode: 0644]
plugins/cordova-plugin-fingerprint-aio/src/android/.gradle/buildOutputCleanup/buildOutputCleanup.lock [new file with mode: 0644]
plugins/cordova-plugin-fingerprint-aio/src/android/.gradle/buildOutputCleanup/cache.properties [new file with mode: 0644]
plugins/cordova-plugin-fingerprint-aio/src/android/.gradle/vcs-1/gc.properties [new file with mode: 0644]
plugins/cordova-plugin-fingerprint-aio/src/android/.project [new file with mode: 0644]
plugins/cordova-plugin-fingerprint-aio/src/android/.settings/org.eclipse.buildship.core.prefs [new file with mode: 0644]
plugins/cordova-plugin-fingerprint-aio/src/android/BiometricActivity.java [new file with mode: 0644]
plugins/cordova-plugin-fingerprint-aio/src/android/Fingerprint.java
plugins/cordova-plugin-fingerprint-aio/src/android/FingerprintAuthenticationDialogFragment.java [deleted file]
plugins/cordova-plugin-fingerprint-aio/src/android/FingerprintUiHelper.java [deleted file]
plugins/cordova-plugin-fingerprint-aio/src/android/PluginError.java [new file with mode: 0644]
plugins/cordova-plugin-fingerprint-aio/src/android/PromptInfo.java [new file with mode: 0644]
plugins/cordova-plugin-fingerprint-aio/src/android/build.gradle [new file with mode: 0644]
plugins/cordova-plugin-fingerprint-aio/src/android/res/biometric_activity.xml [new file with mode: 0644]
plugins/cordova-plugin-fingerprint-aio/src/android/res/styles.xml [new file with mode: 0644]
plugins/cordova-plugin-fingerprint-aio/src/ios/Fingerprint.swift
plugins/cordova-plugin-fingerprint-aio/www/Fingerprint.js
plugins/fetch.json
plugins/ios.json
www/bindcheck.html
www/js/bindcard.js
www/js/bindcheck.js
www/js/login.js
www/js/main.js
www/js/qrcode.js
www/js/security.js
www/js/server.js
www/js/signxy.js
www/js/unsignedcheck.js [new file with mode: 0644]
www/main.html
www/qrcode.html
www/security.html
www/signxy.html
www/unsignedcheck.html [new file with mode: 0644]

index 2eab5ec..6283731 100644 (file)
     <edit-config file="*-Info.plist" mode="merge" target="NSPhotoLibraryUsageDescription">
         <string>APP需要使用您的相册权限,没有该权限将无法完成扫一扫功能</string>
     </edit-config>
-
     <feature name="CDVWKWebViewEngine">
-      <param name="ios-package" value="CDVWKWebViewEngine" />
+        <param name="ios-package" value="CDVWKWebViewEngine" />
     </feature>
-
-    <plugin name="cordova-plugin-fingerprint-aio" spec="~1.7.0">
-        <variable name="FACEID_USAGE_DESCRIPTION" value="认证中..." />
-    </plugin>
     <plugin name="cordova-plugin-touch-id" spec="~3.3.1">
         <variable name="FACEID_USAGE_DESCRIPTION" value=" " />
     </plugin>
index 78076a9..ab7c5fd 100644 (file)
             "integrity": "sha1-SWBrjBWlaI1HKPkuSnMloGHeB/U="
         },
         "cordova-plugin-fingerprint-aio": {
-            "version": "1.7.0",
-            "resolved": "https://registry.npmjs.org/cordova-plugin-fingerprint-aio/-/cordova-plugin-fingerprint-aio-1.7.0.tgz",
-            "integrity": "sha512-pV+JUeEhZUP85nXs9KMpHRClZppVHnpZA5h+8ReKBi4AV4vnzAcpUDBgFN7g3Ra83zmREYI/MqrlZlXn16pg3g==",
+            "version": "3.0.1",
+            "resolved": "https://registry.npmjs.org/cordova-plugin-fingerprint-aio/-/cordova-plugin-fingerprint-aio-3.0.1.tgz",
+            "integrity": "sha512-Sgbv8Ykk74Ov1foEZg77owIqmHZoGktsv41rmW8KAAMf2JE93AawvQdUCYYROnk+ozG3D9ItELa5yhYU8i7Zhw==",
             "requires": {
                 "cordova-plugin-add-swift-support": "^2.0.2"
             }
             "integrity": "sha1-jgOPbdsUvXZa4fS1IW4SCUUR4NA="
         },
         "semver": {
-            "version": "6.1.1",
-            "resolved": "https://registry.npmjs.org/semver/-/semver-6.1.1.tgz",
-            "integrity": "sha512-rWYq2e5iYW+fFe/oPPtYJxYgjBm8sC4rmoGdUOgBB7VnwKt6HrL793l2voH1UlsyYZpJ4g0wfjnTEO1s1NP2eQ=="
+            "version": "6.3.0",
+            "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
+            "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw=="
         },
         "send": {
             "version": "0.17.1",
index e358ecb..5a54e09 100644 (file)
@@ -23,7 +23,7 @@
     "cordova-plugin-device": "^2.0.2",
     "cordova-plugin-disable-ios11-statusbar": "^1.0.0",
     "cordova-plugin-file": "^6.0.1",
-    "cordova-plugin-fingerprint-aio": "^1.7.0",
+    "cordova-plugin-fingerprint-aio": "3.0.1",
     "cordova-plugin-inappbrowser": "^3.0.0",
     "cordova-plugin-jcore": "^1.3.0",
     "cordova-plugin-qrscanner": "^3.0.1",
@@ -35,9 +35,6 @@
   },
   "cordova": {
     "plugins": {
-      "cordova-plugin-fingerprint-aio": {
-        "FACEID_USAGE_DESCRIPTION": "认证中..."
-      },
       "cordova-plugin-touch-id": {},
       "cordova-plugin-whitelist": {},
       "cordova-plugin-advanced-http": {
       "cordova-plugin-app-version": {},
       "cordova-plugin-wkwebview-engine": {},
       "cordova-plugin-brightness": {},
-      "cordova-plugin-file": {}
+      "cordova-plugin-file": {},
+      "cordova-plugin-fingerprint-aio": {
+        "FACEID_USAGE_DESCRIPTION": " "
+      }
     },
     "platforms": [
       "android",
index 2b20a7d..f684e89 100644 (file)
@@ -8,10 +8,6 @@
       "res/xml/config.xml": {
         "parents": {
           "/*": [
-            {
-              "xml": "<feature name=\"Fingerprint\"><param name=\"android-package\" value=\"de.niklasmerz.cordova.fingerprint.Fingerprint\" /></feature>",
-              "count": 1
-            },
             {
               "xml": "<feature name=\"Whitelist\"><param name=\"android-package\" value=\"org.apache.cordova.whitelist.WhitelistPlugin\" /><param name=\"onload\" value=\"true\" /></feature>",
               "count": 1
             {
               "xml": "<feature name=\"Brightness\"><param name=\"android-package\" value=\"org.apache.cordova.plugin.Brightness.BrightnessPlugin\" /></feature>",
               "count": 1
+            },
+            {
+              "xml": "<feature name=\"Fingerprint\"><param name=\"android-package\" value=\"de.niklasmerz.cordova.biometric.Fingerprint\" /></feature>",
+              "count": 1
             }
           ]
         }
       "AndroidManifest.xml": {
         "parents": {
           "/*": [
-            {
-              "xml": "<uses-permission android:name=\"android.permission.USE_FINGERPRINT\" />",
-              "count": 1
-            },
             {
               "xml": "<uses-permission android:name=\"android.permission.WRITE_EXTERNAL_STORAGE\" />",
               "count": 2
             {
               "xml": "<uses-feature android:name=\"android.hardware.camera.front\" android:required=\"false\" />",
               "count": 1
+            },
+            {
+              "xml": "<uses-permission android:name=\"android.permission.USE_BIOMETRIC\" />",
+              "count": 1
+            },
+            {
+              "xml": "<uses-permission android:name=\"android.permission.USE_FINGERPRINT\" />",
+              "count": 1
             }
           ],
           "/manifest": [
             {
               "xml": "<meta-data android:name=\"JPUSH_APPKEY\" android:value=\"d644d997f2cab0551ff704a3\" />",
               "count": 1
+            },
+            {
+              "xml": "<activity android:exported=\"true\" android:name=\"de.niklasmerz.cordova.biometric.BiometricActivity\" android:theme=\"@style/TransparentTheme\" />",
+              "count": 1
             }
           ]
         }
     "cordova-plugin-add-swift-support": {
       "PACKAGE_NAME": "com.dalicitycard.app"
     },
-    "cordova-plugin-fingerprint-aio": {
-      "PACKAGE_NAME": "com.dalicitycard.app"
-    },
     "cordova-plugin-touch-id": {
       "PACKAGE_NAME": "com.dalicitycard.app"
     },
     },
     "cordova-plugin-brightness": {
       "PACKAGE_NAME": "com.dalicitycard.app"
+    },
+    "cordova-plugin-fingerprint-aio": {
+      "PACKAGE_NAME": "com.dalicitycard.app"
     }
   },
   "dependent_plugins": {},
   "modules": [
-    {
-      "id": "cordova-plugin-fingerprint-aio.Fingerprint",
-      "file": "plugins/cordova-plugin-fingerprint-aio/www/Fingerprint.js",
-      "pluginId": "cordova-plugin-fingerprint-aio",
-      "clobbers": [
-        "Fingerprint"
-      ]
-    },
     {
       "id": "cordova-plugin-touch-id.TouchID",
       "file": "plugins/cordova-plugin-touch-id/www/TouchID.js",
       "clobbers": [
         "cordova.plugins.brightness"
       ]
+    },
+    {
+      "id": "cordova-plugin-fingerprint-aio.Fingerprint",
+      "file": "plugins/cordova-plugin-fingerprint-aio/www/Fingerprint.js",
+      "pluginId": "cordova-plugin-fingerprint-aio",
+      "clobbers": [
+        "Fingerprint"
+      ]
     }
   ],
   "plugin_metadata": {
     "cordova-plugin-add-swift-support": "2.0.2",
-    "cordova-plugin-fingerprint-aio": "1.7.0",
     "cordova-plugin-touch-id": "3.3.1",
     "cordova-plugin-whitelist": "1.3.3",
     "cordova-plugin-file": "6.0.1",
     "jpush-phonegap-plugin": "3.7.2",
     "cordova-plugin-app-version": "0.1.9",
     "cordova-plugin-wkwebview-engine": "1.2.1",
-    "cordova-plugin-brightness": "0.1.5"
+    "cordova-plugin-brightness": "0.1.5",
+    "cordova-plugin-fingerprint-aio": "3.0.1"
   }
 }
index c6a120e..b59ebb2 100644 (file)
@@ -91,6 +91,7 @@ ext {
 
 // PLUGIN GRADLE EXTENSIONS START
 apply from: "../cordova-plugin-qrscanner/dlapp-qrscanner.gradle"
+apply from: "../cordova-plugin-fingerprint-aio/app-build.gradle"
 // PLUGIN GRADLE EXTENSIONS END
 
 def hasBuildExtras1 = file('build-extras.gradle').exists()
@@ -175,12 +176,12 @@ android {
         }
         versionCode 12
         versionName '1.3.8'
-        targetSdkVersion 26
+        targetSdkVersion 28
     }
     lintOptions {
         abortOnError false
     }
-    compileSdkVersion 26
+    compileSdkVersion 28
     buildToolsVersion '28.0.3'
     // This code exists for Crosswalk and other Native APIs.
     // By default, we multiply the existing version code in the
index f62d122..6a0228e 100644 (file)
Binary files a/platforms/android/app/release/app-release.apk and b/platforms/android/app/release/app-release.apk differ
index 591c860..556e0db 100644 (file)
@@ -80,8 +80,8 @@
         </receiver>
         <meta-data android:name="JPUSH_CHANNEL" android:value="developer-default" />
         <meta-data android:name="JPUSH_APPKEY" android:value="d644d997f2cab0551ff704a3" />
+        <activity android:exported="true" android:name="de.niklasmerz.cordova.biometric.BiometricActivity" android:theme="@style/TransparentTheme" />
     </application>
-    <uses-permission android:name="android.permission.USE_FINGERPRINT" />
     <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
     <uses-permission android:name="android.permission.CAMERA" android:required="false" />
     <uses-feature android:name="android.hardware.camera" android:required="false" />
     <uses-permission android:name="android.permission.GET_TASKS" />
     <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />
     <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
+    <uses-permission android:name="android.permission.USE_BIOMETRIC" />
+    <uses-permission android:name="android.permission.USE_FINGERPRINT" />
 </manifest>
index fb0347b..dbec6c3 100644 (file)
@@ -1,13 +1,5 @@
 cordova.define('cordova/plugin_list', function(require, exports, module) {
   module.exports = [
-    {
-      "id": "cordova-plugin-fingerprint-aio.Fingerprint",
-      "file": "plugins/cordova-plugin-fingerprint-aio/www/Fingerprint.js",
-      "pluginId": "cordova-plugin-fingerprint-aio",
-      "clobbers": [
-        "Fingerprint"
-      ]
-    },
     {
       "id": "cordova-plugin-touch-id.TouchID",
       "file": "plugins/cordova-plugin-touch-id/www/TouchID.js",
@@ -345,41 +337,16 @@ cordova.define('cordova/plugin_list', function(require, exports, module) {
       ]
     },
     {
-      "id": "cordova-plugin-file-opener2.FileOpener2",
-      "file": "plugins/cordova-plugin-file-opener2/www/plugins.FileOpener2.js",
-      "pluginId": "cordova-plugin-file-opener2",
-      "clobbers": [
-        "cordova.plugins.fileOpener2"
-      ]
-    },
-    {
-      "id": "cordova-plugin-file-transfer.FileTransferError",
-      "file": "plugins/cordova-plugin-file-transfer/www/FileTransferError.js",
-      "pluginId": "cordova-plugin-file-transfer",
-      "clobbers": [
-        "window.FileTransferError"
-      ]
-    },
-    {
-      "id": "cordova-plugin-file-transfer.FileTransfer",
-      "file": "plugins/cordova-plugin-file-transfer/www/FileTransfer.js",
-      "pluginId": "cordova-plugin-file-transfer",
-      "clobbers": [
-        "window.FileTransfer"
-      ]
-    },
-    {
-      "id": "cordova-plugin-crop.CropPlugin",
-      "file": "plugins/cordova-plugin-crop/www/crop.js",
-      "pluginId": "cordova-plugin-crop",
+      "id": "cordova-plugin-fingerprint-aio.Fingerprint",
+      "file": "plugins/cordova-plugin-fingerprint-aio/www/Fingerprint.js",
+      "pluginId": "cordova-plugin-fingerprint-aio",
       "clobbers": [
-        "plugins.crop"
+        "Fingerprint"
       ]
     }
   ];
   module.exports.metadata = {
     "cordova-plugin-add-swift-support": "2.0.2",
-    "cordova-plugin-fingerprint-aio": "1.7.0",
     "cordova-plugin-touch-id": "3.3.1",
     "cordova-plugin-whitelist": "1.3.3",
     "cordova-plugin-file": "6.0.1",
@@ -396,8 +363,6 @@ cordova.define('cordova/plugin_list', function(require, exports, module) {
     "cordova-plugin-app-version": "0.1.9",
     "cordova-plugin-wkwebview-engine": "1.2.1",
     "cordova-plugin-brightness": "0.1.5",
-    "cordova-plugin-file-opener2": "2.2.1",
-    "cordova-plugin-file-transfer": "1.7.1",
-    "cordova-plugin-crop": "0.3.1"
+    "cordova-plugin-fingerprint-aio": "3.0.1"
   };
 });
\ No newline at end of file
index f7e91a2..7af7d38 100644 (file)
@@ -81,9 +81,15 @@ var app = {
                     window.localStorage.setItem("idno", idno);
                     window.localStorage.setItem("phoneX",ret.phonex);
                     window.localStorage.setItem("personid", ret.personid);
+                    window.localStorage.setItem("userid", ret.personid);
                     window.localStorage.setItem("signed", ret.signed);
                     window.localStorage.setItem("paypwdset", ret.paypwdset);
-                    window.location = "bindcheck.html";
+                    if(ret.signed=='yes'){
+                        window.location = "main.html"
+                    }else{
+                        window.location = "bindcheck.html";
+                    }
+                    
                 } else {
                     if (ret.code == -1) {
                         $.alert(ret.msg, "提示", function() {
index 7931a48..88950f3 100644 (file)
@@ -7,6 +7,29 @@ var app = {
   
     onDeviceReady: function() {
         this.receivedEvent('deviceready');
+        this.loginWithFinger();
+    },
+    loginWithFinger:function(){
+        let loginfinger =  window.localStorage.getItem("loginfinger");
+        let phone =  window.localStorage.getItem("phone");
+        let pwd =  window.localStorage.getItem("localpwd");
+        let _this = this;
+        if(phone&&pwd&&loginfinger&&loginfinger=='1'){
+              Fingerprint.isAvailable(function(result){
+                 Fingerprint.show({
+                       title:"正在使用指纹或人脸登录",
+                       description: "请验证您的指纹或人脸"
+                     }, function(success){
+                        _this.loginIt(phone,pwd);
+                     }, function(error){
+                       $.alert("验证失败,指纹或人脸错误,请使用密码登录", "提示");
+                       //$("#login").removeAttr("checked");
+                     });
+
+             }, function(message){
+                  $.alert("设备不支持指纹或人脸,请使用密码登录", "提示");
+             });
+        }
     },
 
     // Update DOM on a Received Event
@@ -29,7 +52,9 @@ var app = {
         if(isEmpty(phone)||isEmpty(pwd)){
             return;
         }
-        //loadingElement('loginBtn', '登录中...')
+        this.loginIt(phone,pwd);
+    },
+    loginIt: function(phone,pwd){
         $.showLoading("登录中");
         var param={
             "username":phone,
@@ -56,6 +81,7 @@ var app = {
                  window.localStorage.setItem("signed",ret.signed); 
                  window.localStorage.setItem("paypwdset",ret.paypwdset); 
                  window.localStorage.setItem("name",ret.name);  
+                 window.localStorage.setItem("localpwd",pwd);  
                  window.location = "main.html";  
                }     
             }else{
index bc93d91..8c211e9 100644 (file)
@@ -111,6 +111,25 @@ var app = {
                 })
             })
         });
+        $('#accsignbtn').click(function() {
+            app.checkBefore(function() {
+                var signed = window.localStorage.getItem("signed");
+                var cum = new auiDialog({});
+                 if (isEmpty(signed) || signed != 'yes') {
+                    var confirm = cum.alert({
+                        title: "提示",
+                        msg: '您尚未签约市民卡免密代扣签约协议,无法使用该功能',
+                        buttons: ['取消', '去签约']
+                    }, function(ret) {
+                        if (ret.buttonIndex == 2) {
+                           app.toSignCode();
+                        }
+                    })
+                }else{
+                    window.location = 'signxycheck.html'
+                }
+            })
+        });
         this.initData();
         this.backBtn();
     },
@@ -153,13 +172,15 @@ var app = {
         $("#loaddata").show()
         $("#nodata").hide();
         var param = {
-            "pageno": 1
+            "pageno": 1,
+            "platform":"android"
         }
         V1Bills(param, function(ok, ret) {
             if (ok) {
-                //console.log(ret)
+                console.log(ret)
                 if (ret.code == 200) {
-                    app.checkVersion(ret.version,ret.minversion,ret.versionmsg);
+                    //app.checkVersion(ret.version,ret.minversion,ret.versionmsg,ret.versionurl);
+                    app.checkVersion("1.3.9","1","new func","https://shouji.baidu.com/software/26706357.html");
                     $("#maingt").text(ret.t + "!")
                     $("#user-amount").text(ret.amount)
                     $("#user-point").text(ret.point)
@@ -196,14 +217,21 @@ var app = {
             }
         })
     },
-    checkVersion:function(ver,minver,msg){
+    checkVersion:function(ver,minver,m,url){
         cordova.getAppVersion.getVersionNumber(function (version) {
             //alert(version);
-            if(version<minver){
-                //TODO 强制升级
-                alert("当前版本过低,为了不影响您的使用,请先升级");
-            }else if(ver>version){
-                alert("有新的版本");    
+            alert(version);
+            if(ver>version){
+                var cum = new auiDialog({});
+                var confirm = cum.alert({
+                    title: "有新的版本",
+                    msg: m,
+                    buttons: ['取消', '去更新']
+                }, function(ret) {
+                    if (ret.buttonIndex == 2) {
+                       cordova.InAppBrowser.open(url, '_system', 'location=no,toolbar=yes,toolbarposition=top,closebuttoncaption=关闭');
+                    }
+                })  
             }
         });
     },
@@ -282,38 +310,40 @@ var app = {
         }
     },
     checkOther: function(callback) {
-        var payseted = window.localStorage.getItem("paypwdset");
         var signed = window.localStorage.getItem("signed");
         var cum = new auiDialog({});
-        console.log(payseted, signed)
-        if (isEmpty(payseted) || !payseted || payseted != 'true') {
+
+        if (isEmpty(signed) || signed != 'yes') {
             var confirm = cum.alert({
                 title: "提示",
-                msg: '您还没有设置支付密码,无法使用该功能',
-                buttons: ['取消', '去设置']
+                msg: '您尚未签约市民卡免密代扣签约协议,无法使用该功能',
+                buttons: ['取消', '去签约']
             }, function(ret) {
                 if (ret.buttonIndex == 2) {
-                    window.location = 'paypwdset.html'
+                   app.toSignCode();
                 }
             })
         } else {
-            if (isEmpty(signed) || signed != 'yes') {
-                var confirm = cum.alert({
-                    title: "提示",
-                    msg: '您尚未签约代扣免密付协议,无法使用该功能',
-                    buttons: ['取消', '去签约']
-                }, function(ret) {
-                    if (ret.buttonIndex == 2) {
-                        window.location = 'signxy.html'
-                    }
-                })
-            } else {
-                if (callback) {
-                    callback()
-                }
+            if (callback) {
+                callback()
             }
         }
     },
+    toSignCode: function(){
+        var param = {
+        }
+        V1Bindcardcode(param, function(ok, ret) {
+            if (ok) {
+                if (ret.code == 200) {
+                    window.location = 'bindcheck.html'
+                } else {
+                    $.alert(ret.msg, "错误");
+                }
+            } else {
+                $.alert("请求失败了 " + ret.status + ",请稍后再试", "错误");
+            }
+        })
+    },
     toSign: function() {
         window.location = 'signxycheck.html'
     },
index b9d81b9..51b2aa1 100644 (file)
@@ -22,6 +22,10 @@ var app = {
             console.log(err);
           });
         }
+        document.addEventListener("backbutton", function(e){
+               e.preventDefault();
+               app.backTo();
+            }, false);
     },
     loadQrcode: function() {
         $.showLoading("加载中");
@@ -62,6 +66,7 @@ var app = {
             if (ok) {
                 if (ret.code == 200) {
                     $.hideLoading();
+                    $("#qrcode").html('');
                     var qrcode = new QRCode(document.getElementById("qrcode"), {
                       text: ret.qrcode,
                       width: 200,
index f12a1cc..d159a40 100644 (file)
@@ -5,23 +5,68 @@ var app = {
         document.addEventListener('deviceready', this.onDeviceReady.bind(this), false);
     },
     onDeviceReady: function() {
+      let loginfinger =  window.localStorage.getItem("loginfinger");
+       if(loginfinger&&loginfinger=='1'){
+        $("#login").prop("checked","checked");
+       }
     },
     editPwd: function() {
        window.location = "editpwd.html";
     },
     toPayPwd: function() {
-       window.location = "paypwdmng.html";
+      var payseted = window.localStorage.getItem("paypwdset");
+      if (isEmpty(payseted) || !payseted || payseted != 'true') {
+          window.location = 'paypwdset.html'
+      } else{
+        window.location = "paypwdmng.html";
+      }
     },
     logout:function(){
         window.localStorage.removeItem("token");
         window.location = "login.html";
     },
     loginByTouchId: function() {
-       Fingerprint.isAvailable(function(result){
-            alert("Fingerprint available");
-       }, function(message){
-            alert(message);
-       });
+       let loginfinger =  window.localStorage.getItem("loginfinger");
+       if(loginfinger&&loginfinger=='1'){
+          var confirm = new auiDialog({}).alert({
+                title: "提示",
+                msg: '确定关闭指纹或人脸登录吗?',
+                buttons: ['取消', '确定']
+            }, function(ret) {
+                if (ret.buttonIndex == 2) {
+                    window.localStorage.setItem("loginfinger","0");
+                    $("#login").removeAttr("checked");
+                }else{
+                  //$("#login").attr("checked","checked");
+                }
+               });
+       }else{
+        let pwd =  window.localStorage.getItem("localpwd");
+        if(!pwd){
+          $.alert("长时间未登录,需要先登录后再使用该功能", "提示",function(){
+             window.localStorage.removeItem("token");
+             window.location = "login.html";
+          });
+          return;
+        }
+         $("#login").removeAttr("checked");
+         Fingerprint.isAvailable(function(result){
+             Fingerprint.show({
+                   title:"大理市民卡开启指纹或人脸登录",
+                   description: "请验证您的指纹或人脸"
+                 }, function(success){
+                    window.localStorage.setItem("loginfinger","1");
+                    $.alert("验证成功,您已开启指纹或人脸登录", "提示");
+                    $("#login").prop("checked","checked");
+                 }, function(error){
+                   $.alert("验证失败,指纹或人脸错误次数过多,请稍后再试", "提示");
+                   //$("#login").removeAttr("checked");
+                 });
+
+         }, function(message){
+              $.alert("设备不支持指纹或人脸", "提示");
+         });
+       }
     }
 };
 app.initialize();
index ba99748..426bf2d 100644 (file)
@@ -7,6 +7,10 @@ var CURRENT_INDEX=1;
 if (dev) {
     SERVER = "http://172.28.43.7:8099/payapi/mobileapi";
 }
+function V1Bindcardcode(param,callback) {
+    ajaxPost("/v1/bindcardcode", param, callback)
+}
+
 function V1Unbindcard(param,callback){
     ajaxPost("/v1/unbindcard", param, callback)
 }
index f97f3d4..4ee8598 100644 (file)
@@ -14,10 +14,10 @@ var app = {
                 if(ret.code==200){
                     $("#content").html(ret.page);
                     if(isEmpty(ret.signed)||ret.signed!='yes'){
-                        $("#btn").show();   
-                        $("#content").css("bottom","135px");
+                        //$("#btn").show();   
+                        //$("#content").css("bottom","135px");
                     }else{
-                        $("#content").css("bottom","10px");
+                        //$("#content").css("bottom","10px");
                     }
                 }else{
                     $.alert(ret.msg, "错误");
index b357ca3..c8bb590 100644 (file)
                         <div class="aui-list-item-right" id="userbank"></div>
                     </div>
                 </li>
-                <li class="aui-list-item" onclick="app.toSign()">
+                <li class="aui-list-item" id="accsignbtn">
                     <div class="aui-list-item-label-icon">
                         <i class="aui-iconfont aui-icon-pencil aui-text-danger"></i>
                     </div>
index 3982139..22ecb6c 100644 (file)
@@ -1,8 +1,28 @@
 cordova.define("cordova-plugin-fingerprint-aio.Fingerprint", function(require, exports, module) {
 /*global cordova */
 
-function Fingerprint() {
-}
+var Fingerprint = function() {
+};
+
+// Plugin Errors
+Fingerprint.prototype.BIOMETRIC_UNKNOWN_ERROR = -100;
+Fingerprint.prototype.BIOMETRIC_UNAVAILABLE = -101;
+Fingerprint.prototype.BIOMETRIC_AUTHENTICATION_FAILED = -102;
+Fingerprint.prototype.BIOMETRIC_SDK_NOT_SUPPORTED = -103;
+Fingerprint.prototype.BIOMETRIC_HARDWARE_NOT_SUPPORTED = -104;
+Fingerprint.prototype.BIOMETRIC_PERMISSION_NOT_GRANTED = -105;
+Fingerprint.prototype.BIOMETRIC_NOT_ENROLLED = -106;
+Fingerprint.prototype.BIOMETRIC_INTERNAL_PLUGIN_ERROR = -107;
+Fingerprint.prototype.BIOMETRIC_DISMISSED = -108;
+Fingerprint.prototype.BIOMETRIC_PIN_OR_PATTERN_DISMISSED = -109;
+Fingerprint.prototype.BIOMETRIC_SCREEN_GUARD_UNSECURED = -110;
+Fingerprint.prototype.BIOMETRIC_LOCKED_OUT = -111;
+Fingerprint.prototype.BIOMETRIC_LOCKED_OUT_PERMANENT = -112;
+
+// Biometric types
+Fingerprint.prototype.BIOMETRIC_TYPE_FINGERPRINT = "finger";
+Fingerprint.prototype.BIOMETRIC_TYPE_FACE = "face";
+Fingerprint.prototype.BIOMETRIC_TYPE_COMMON = "biometric";
 
 Fingerprint.prototype.show = function (params, successCallback, errorCallback) {
   cordova.exec(
index 5ce5788..a64f153 100644 (file)
@@ -24,9 +24,9 @@
         <div style="background: #fff;text-align: center;" id="qrcode"></div>
     </div>
     <p style="text-align: center;margin-top:40px;color:#999">请将二维码对准扫描设备</p>
-    <!--<div style="padding: 30px;">
-        <div class="aui-btn aui-btn-block aui-btn-info" tapmode onclick="window.location.reload();">刷新二维码</div>
-    </div>-->
+    <div style="padding: 30px;">
+        <div class="aui-btn aui-btn-block aui-btn-info" tapmode onclick="app.refresh()">刷新二维码</div>
+    </div>
 </body>
 </html>
 <script type="text/javascript" src="cordova.js"></script>
index 39a40ca..971cc59 100644 (file)
                     <div class="aui-list-item-right"></div>
                 </div>
             </li>
-            <!--<li class="aui-list-item" onclick="app.loginByTouchId()">
+            <li class="aui-list-item" onclick="app.loginByTouchId()">
                 <div class="aui-list-item-label-icon">
-                    <i class="aui-iconfont aui-icon-lock aui-text-info"></i>
+                    <i class="aui-iconfont aui-icon-gear aui-text-info"></i>
                 </div>
                 <div class="aui-list-item-inner ">
                     <div class="aui-list-item-title">指纹\人脸登录</div>
-                    <div class="aui-list-item-right"><input type="checkbox" id="login" class="aui-switch" ></div>
+                    <div class="aui-list-item-right"><input type="checkbox" id="login" class="aui-switch" disabled ></div>
                 </div>
-            </li>-->
+            </li>
+        </ul>
+    </section>
+    <section class="aui-content aui-margin-b-15 aui-margin-t-10">
+        <ul class="aui-list aui-list-in aui-margin-t-10 ">
             <li class="aui-list-item" onclick="app.toPayPwd()">
                 <div class="aui-list-item-label-icon">
                     <i class="aui-iconfont aui-icon-pencil aui-text-danger"></i>
@@ -50,9 +54,6 @@
                 </div>
             </li>
         </ul>
-        <div style="padding: 20px;margin-top: 40px;">
-            <a href="javascript:app.logout();" class="weui-btn weui-btn_warn">退出登录</a>
-        </div>
     </section>
 </body>
 
index cb0f1ba..c22eda3 100644 (file)
     <link rel="stylesheet" type="text/css" href="css/aui.css">
     <link rel="stylesheet" type="text/css" href="css/weui.min.css">
     <link rel="stylesheet" type="text/css" href="css/jquery-weui.min.css">
-    <title>签约代扣免密支付协议</title>
+    <title>市民卡免密代扣签约协议</title>
 </head>
 <body>
     <header class="aui-bar aui-bar-nav" style="padding-top:25px;">
-        <a class="aui-pull-left" href="main.html">
+        <a class="aui-pull-left" href="javascript:window.history.back()">
             <span class="aui-iconfont aui-icon-left"></span>
         </a>
-        <div class="aui-title">签约代扣免密支付协议</div>
+        <div class="aui-title">市民卡免密代扣签约协议</div>
     </header>
-    <div style="padding:10px;overflow: scroll;position: absolute;top:74px;bottom:135px;left: 0;right: 0" id="content">
+    <div style="padding:10px;overflow: scroll;position: absolute;top:74px;bottom:10px;left: 0;right: 0" id="content">
         
     </div>
-    <div class="weui-footer weui-footer_fixed-bottom" style="background: #fff;display: none;" id="btn">
-            <div style="margin-top: 10px;">
-                <label for="agree" class="weui-agree" style="padding: .5em 5px .5em 15px;display: inline-block;">
-                    <input id="agree" type="checkbox" class="weui-agree__checkbox" value="yes">
-                    <span class="weui-agree__text">
-                        我已阅读并同意该协议
-                    </span>
-                </label>
-            </div>
-            <section class="aui-content-padded" style="margin-top: 20px;">
-                <div class="aui-btn aui-btn-block aui-btn-info"  tapmode onclick="app.agreeXY()">签约代扣协议</div>
-            </section>
-    </div>
+   
 </body>
 
 </html>
diff --git a/platforms/android/app/src/main/java/de/niklasmerz/cordova/biometric/BiometricActivity.java b/platforms/android/app/src/main/java/de/niklasmerz/cordova/biometric/BiometricActivity.java
new file mode 100644 (file)
index 0000000..0d6d20e
--- /dev/null
@@ -0,0 +1,159 @@
+package de.niklasmerz.cordova.biometric;
+
+import android.app.Activity;
+import android.app.KeyguardManager;
+import android.content.Intent;
+import android.os.Build;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Looper;
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
+import android.support.v4.content.ContextCompat;
+import android.support.v7.app.AppCompatActivity;
+
+import com.exxbrain.android.biometric.BiometricPrompt;
+
+import java.util.concurrent.Executor;
+
+public class BiometricActivity extends AppCompatActivity {
+
+    private static final int REQUEST_CODE_CONFIRM_DEVICE_CREDENTIALS = 2;
+    private PromptInfo mPromptInfo;
+
+    @Override
+    protected void onCreate(@Nullable Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        setTitle(null);
+        int layout = getResources()
+                .getIdentifier("biometric_activity", "layout", getPackageName());
+        setContentView(layout);
+
+        if (savedInstanceState != null) {
+            return;
+        }
+
+        mPromptInfo = new PromptInfo.Builder(getIntent().getExtras()).build();
+        authenticate();
+
+    }
+
+    private void authenticate() {
+        final Handler handler = new Handler(Looper.getMainLooper());
+        Executor executor = handler::post;
+
+        BiometricPrompt biometricPrompt =
+                new BiometricPrompt(this, executor, mAuthenticationCallback);
+
+        BiometricPrompt.PromptInfo.Builder promptInfoBuilder = new BiometricPrompt.PromptInfo.Builder()
+                .setTitle(mPromptInfo.getTitle())
+                .setSubtitle(mPromptInfo.getSubtitle())
+                .setDescription(mPromptInfo.getDescription());
+
+        if (mPromptInfo.isDeviceCredentialAllowed()
+                && Build.VERSION.SDK_INT <= Build.VERSION_CODES.P) { // TODO: remove after fix https://issuetracker.google.com/issues/142740104
+            promptInfoBuilder.setDeviceCredentialAllowed(true);
+        } else {
+            promptInfoBuilder.setNegativeButtonText(mPromptInfo.getCancelButtonTitle());
+        }
+
+        biometricPrompt.authenticate(promptInfoBuilder.build());
+    }
+
+    private BiometricPrompt.AuthenticationCallback mAuthenticationCallback =
+            new BiometricPrompt.AuthenticationCallback() {
+
+                @Override
+                public void onAuthenticationError(int errorCode, @NonNull CharSequence errString) {
+                    super.onAuthenticationError(errorCode, errString);
+                    onError(errorCode, errString);
+                }
+
+                @Override
+                public void onAuthenticationSucceeded(@NonNull BiometricPrompt.AuthenticationResult result) {
+                    super.onAuthenticationSucceeded(result);
+                    finishWithSuccess();
+                }
+
+                @Override
+                public void onAuthenticationFailed() {
+                    super.onAuthenticationFailed();
+                }
+            };
+
+
+    // TODO: remove after fix https://issuetracker.google.com/issues/142740104
+    private void showAuthenticationScreen() {
+        KeyguardManager keyguardManager = ContextCompat
+                .getSystemService(this, KeyguardManager.class);
+        if (keyguardManager == null
+                || android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.LOLLIPOP) {
+            return;
+        }
+        if (keyguardManager.isKeyguardSecure()) {
+            Intent intent = keyguardManager
+                    .createConfirmDeviceCredentialIntent(mPromptInfo.getTitle(), mPromptInfo.getDescription());
+            this.startActivityForResult(intent, REQUEST_CODE_CONFIRM_DEVICE_CREDENTIALS);
+        } else {
+            // Show a message that the user hasn't set up a lock screen.
+            finishWithError(PluginError.BIOMETRIC_SCREEN_GUARD_UNSECURED);
+        }
+    }
+
+    // TODO: remove after fix https://issuetracker.google.com/issues/142740104
+    @Override
+    public void onActivityResult(int requestCode, int resultCode, Intent data) {
+        if (requestCode == REQUEST_CODE_CONFIRM_DEVICE_CREDENTIALS) {
+            if (resultCode == Activity.RESULT_OK) {
+                finishWithSuccess();
+            } else {
+                finishWithError(PluginError.BIOMETRIC_PIN_OR_PATTERN_DISMISSED);
+            }
+        }
+    }
+
+    private void onError(int errorCode, @NonNull CharSequence errString) {
+
+        switch (errorCode)
+        {
+            case BiometricPrompt.ERROR_USER_CANCELED:
+            case BiometricPrompt.ERROR_CANCELED:
+                finishWithError(PluginError.BIOMETRIC_DISMISSED);
+                return;
+            case BiometricPrompt.ERROR_NEGATIVE_BUTTON:
+                // TODO: remove after fix https://issuetracker.google.com/issues/142740104
+                if (Build.VERSION.SDK_INT > Build.VERSION_CODES.P && mPromptInfo.isDeviceCredentialAllowed()) {
+                    showAuthenticationScreen();
+                    return;
+                }
+                finishWithError(PluginError.BIOMETRIC_DISMISSED);
+                break;
+            case BiometricPrompt.ERROR_LOCKOUT:
+                finishWithError(PluginError.BIOMETRIC_LOCKED_OUT.getValue(), errString.toString());
+                break;
+            case BiometricPrompt.ERROR_LOCKOUT_PERMANENT:
+                finishWithError(PluginError.BIOMETRIC_LOCKED_OUT_PERMANENT.getValue(), errString.toString());
+                break;
+            default:
+                finishWithError(errorCode, errString.toString());
+        }
+    }
+
+    private void finishWithSuccess() {
+        setResult(RESULT_OK);
+        finish();
+    }
+
+    private void finishWithError(PluginError error) {
+        finishWithError(error.getValue(), error.getMessage());
+    }
+
+    private void finishWithError(int code, String message) {
+        Intent data = new Intent();
+        data.putExtra("code", code);
+        data.putExtra("message", message);
+        setResult(RESULT_CANCELED, data);
+        finish();
+    }
+}
diff --git a/platforms/android/app/src/main/java/de/niklasmerz/cordova/biometric/Fingerprint.java b/platforms/android/app/src/main/java/de/niklasmerz/cordova/biometric/Fingerprint.java
new file mode 100644 (file)
index 0000000..5bfe78e
--- /dev/null
@@ -0,0 +1,132 @@
+package de.niklasmerz.cordova.biometric;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.os.Build;
+import android.os.Bundle;
+import android.util.Log;
+
+import com.exxbrain.android.biometric.BiometricManager;
+
+import org.apache.cordova.CallbackContext;
+import org.apache.cordova.CordovaInterface;
+import org.apache.cordova.CordovaPlugin;
+import org.apache.cordova.CordovaWebView;
+import org.apache.cordova.PluginResult;
+import org.json.JSONArray;
+import org.json.JSONException;
+import org.json.JSONObject;
+
+public class Fingerprint extends CordovaPlugin {
+
+    private static final String TAG = "Fingerprint";
+    private CallbackContext mCallbackContext = null;
+
+    private static final int REQUEST_CODE_BIOMETRIC = 1;
+    private PromptInfo.Builder mPromptInfoBuilder;
+
+    public void initialize(CordovaInterface cordova, CordovaWebView webView) {
+        super.initialize(cordova, webView);
+        Log.v(TAG, "Init Fingerprint");
+        mPromptInfoBuilder = new PromptInfo.Builder(cordova.getActivity());
+    }
+
+    public boolean execute(final String action, JSONArray args, CallbackContext callbackContext) {
+
+        this.mCallbackContext = callbackContext;
+        Log.v(TAG, "Fingerprint action: " + action);
+
+        if (action.equals("authenticate")) {
+            executeAuthenticate(args);
+            return true;
+
+        } else if (action.equals("isAvailable")){
+            executeIsAvailable();
+            return true;
+        }
+
+        return false;
+    }
+
+    private void executeIsAvailable() {
+        PluginError error = canAuthenticate();
+        if (error != null) {
+            sendError(error);
+        } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P){
+            sendSuccess("biometric");
+        } else {
+            sendSuccess("finger");
+        }
+    }
+
+    private void executeAuthenticate(JSONArray args) {
+        PluginError error = canAuthenticate();
+        if (error != null) {
+            sendError(error);
+            return;
+        }
+        cordova.getActivity().runOnUiThread(() -> {
+            mPromptInfoBuilder.parseArgs(args);
+            Intent intent = new Intent(cordova.getActivity().getApplicationContext(), BiometricActivity.class);
+            intent.putExtras(mPromptInfoBuilder.build().getBundle());
+            this.cordova.startActivityForResult(this, intent, REQUEST_CODE_BIOMETRIC);
+        });
+        PluginResult pluginResult = new PluginResult(PluginResult.Status.NO_RESULT);
+        pluginResult.setKeepCallback(true);
+        this.mCallbackContext.sendPluginResult(pluginResult);
+    }
+
+    @Override
+    public void onActivityResult(int requestCode, int resultCode, Intent intent) {
+        super.onActivityResult(requestCode, resultCode, intent);
+        if (requestCode != REQUEST_CODE_BIOMETRIC) {
+            return;
+        }
+        if (resultCode == Activity.RESULT_OK) {
+            sendSuccess("biometric_success");
+        } else if (intent != null) {
+            Bundle extras = intent.getExtras();
+            sendError(extras.getInt("code"), extras.getString("message"));
+        } else {
+            sendError(PluginError.BIOMETRIC_DISMISSED);
+        }
+    }
+
+    private PluginError canAuthenticate() {
+        int error = BiometricManager.from(cordova.getContext()).canAuthenticate();
+        switch (error) {
+            case BiometricManager.BIOMETRIC_ERROR_HW_UNAVAILABLE:
+            case BiometricManager.BIOMETRIC_ERROR_NO_HARDWARE:
+                return PluginError.BIOMETRIC_HARDWARE_NOT_SUPPORTED;
+            case BiometricManager.BIOMETRIC_ERROR_NONE_ENROLLED:
+                return PluginError.BIOMETRIC_NOT_ENROLLED;
+            default:
+                return null;
+        }
+    }
+
+    private void sendError(int code, String message) {
+        JSONObject resultJson = new JSONObject();
+        try {
+            resultJson.put("code", code);
+            resultJson.put("message", message);
+
+            PluginResult result = new PluginResult(PluginResult.Status.ERROR, resultJson);
+            result.setKeepCallback(true);
+            cordova.getActivity().runOnUiThread(() ->
+                    Fingerprint.this.mCallbackContext.sendPluginResult(result));
+        } catch (JSONException e) {
+            Log.e(TAG, e.getMessage(), e);
+        }
+    }
+
+    private void sendError(PluginError error) {
+        sendError(error.getValue(), error.getMessage());
+    }
+
+    private void sendSuccess(String message) {
+        Log.e(TAG, message);
+        cordova.getActivity().runOnUiThread(() ->
+                this.mCallbackContext.success(message));
+    }
+}
diff --git a/platforms/android/app/src/main/java/de/niklasmerz/cordova/biometric/PluginError.java b/platforms/android/app/src/main/java/de/niklasmerz/cordova/biometric/PluginError.java
new file mode 100644 (file)
index 0000000..1a4a5db
--- /dev/null
@@ -0,0 +1,35 @@
+package de.niklasmerz.cordova.biometric;
+
+public enum PluginError {
+
+    BIOMETRIC_AUTHENTICATION_FAILED(-102, "Authentication failed"),
+    BIOMETRIC_HARDWARE_NOT_SUPPORTED(-104),
+    BIOMETRIC_NOT_ENROLLED(-106),
+    BIOMETRIC_DISMISSED(-108),
+    BIOMETRIC_PIN_OR_PATTERN_DISMISSED(-109),
+    BIOMETRIC_SCREEN_GUARD_UNSECURED(-110,
+            "Go to 'Settings -> Security -> Screenlock' to set up a lock screen"),
+    BIOMETRIC_LOCKED_OUT(-111),
+    BIOMETRIC_LOCKED_OUT_PERMANENT(-112);
+
+    private int value;
+    private String message;
+
+    PluginError(int value) {
+        this.value = value;
+        this.message = this.name();
+    }
+
+    PluginError(int value, String message) {
+        this.value = value;
+        this.message = message;
+    }
+
+    public int getValue() {
+        return value;
+    }
+
+    public String getMessage() {
+        return message;
+    }
+}
diff --git a/platforms/android/app/src/main/java/de/niklasmerz/cordova/biometric/PromptInfo.java b/platforms/android/app/src/main/java/de/niklasmerz/cordova/biometric/PromptInfo.java
new file mode 100644 (file)
index 0000000..31ed0dd
--- /dev/null
@@ -0,0 +1,136 @@
+package de.niklasmerz.cordova.biometric;
+
+import android.content.Context;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
+import android.os.Bundle;
+import android.util.Log;
+
+import org.json.JSONArray;
+import org.json.JSONException;
+import org.json.JSONObject;
+
+class PromptInfo {
+
+    private static final String DISABLE_BACKUP = "disableBackup";
+    private static final String TITLE = "title";
+    private static final String SUBTITLE = "subtitle";
+    private static final String DESCRIPTION = "description";
+    private static final String FALLBACK_BUTTON_TITLE = "fallbackButtonTitle";
+    private static final String CANCEL_BUTTON_TITLE = "cancelButtonTitle";
+
+    private Bundle bundle = new Bundle();
+
+    Bundle getBundle() {
+        return bundle;
+    }
+
+    String getTitle() {
+        return bundle.getString(TITLE);
+    }
+
+    String getSubtitle() {
+        return bundle.getString(SUBTITLE);
+    }
+
+    String getDescription() {
+        return bundle.getString(DESCRIPTION);
+    }
+
+    boolean isDeviceCredentialAllowed() {
+        return !bundle.getBoolean(DISABLE_BACKUP);
+    }
+
+    String getFallbackButtonTitle() {
+        return bundle.getString(FALLBACK_BUTTON_TITLE);
+    }
+
+    String getCancelButtonTitle() {
+        return bundle.getString(CANCEL_BUTTON_TITLE);
+    }
+
+    public static final class Builder {
+        private static final String TAG = "PromptInfo.Builder";
+        private Bundle bundle;
+        private boolean disableBackup = false;
+        private String title;
+        private String subtitle = null;
+        private String description = null;
+        private String fallbackButtonTitle = "Use backup";
+        private String cancelButtonTitle = "Cancel";
+
+        Builder(Context context) {
+            PackageManager packageManager = context.getPackageManager();
+            try {
+                ApplicationInfo app = packageManager
+                        .getApplicationInfo(context.getPackageName(), 0);
+                title = packageManager.getApplicationLabel(app) + " Biometric Sign On";
+            } catch (PackageManager.NameNotFoundException e) {
+                title = "Biometric Sign On";
+            }
+        }
+
+        Builder(Bundle bundle) {
+            this.bundle = bundle;
+        }
+
+        public PromptInfo build() {
+            PromptInfo promptInfo = new PromptInfo();
+
+            if (this.bundle != null) {
+                promptInfo.bundle = bundle;
+                return promptInfo;
+            }
+
+            Bundle bundle = new Bundle();
+            bundle.putString(SUBTITLE, this.subtitle);
+            bundle.putString(TITLE, this.title);
+            bundle.putString(DESCRIPTION, this.description);
+            bundle.putString(FALLBACK_BUTTON_TITLE, this.fallbackButtonTitle);
+            bundle.putString(CANCEL_BUTTON_TITLE, this.cancelButtonTitle);
+            bundle.putBoolean(DISABLE_BACKUP, this.disableBackup);
+            promptInfo.bundle = bundle;
+
+            return promptInfo;
+        }
+
+        void parseArgs(JSONArray args) {
+            JSONObject argsObject;
+            try {
+                argsObject = args.getJSONObject(0);
+            } catch (JSONException e) {
+                Log.e(TAG, "Can't parse args. Defaults will be used.", e);
+                return;
+            }
+            disableBackup = getBooleanArg(argsObject, DISABLE_BACKUP, disableBackup);
+            title = getStringArg(argsObject, TITLE, title);
+            subtitle = getStringArg(argsObject, SUBTITLE, subtitle);
+            description = getStringArg(argsObject, DESCRIPTION, description);
+            fallbackButtonTitle = getStringArg(argsObject, FALLBACK_BUTTON_TITLE, "Use Backup");
+            cancelButtonTitle = getStringArg(argsObject, CANCEL_BUTTON_TITLE, "Cancel");
+        }
+
+        private Boolean getBooleanArg(JSONObject argsObject, String name, Boolean defaultValue) {
+            if (argsObject.has(name)){
+                try {
+                    return argsObject.getBoolean(name);
+                } catch (JSONException e) {
+                    Log.e(TAG, "Can't parse '" + name + "'. Default will be used.", e);
+                }
+            }
+            return defaultValue;
+        }
+
+        private String getStringArg(JSONObject argsObject, String name, String defaultValue) {
+            if (argsObject.optString(name) != null
+                    && !argsObject.optString(name).isEmpty()){
+                try {
+                    return argsObject.getString(name);
+                } catch (JSONException e) {
+                    Log.e(TAG, "Can't parse '" + name + "'. Default will be used.", e);
+                }
+            }
+            return defaultValue;
+        }
+    }
+}
diff --git a/platforms/android/app/src/main/java/de/niklasmerz/cordova/fingerprint/Fingerprint.java b/platforms/android/app/src/main/java/de/niklasmerz/cordova/fingerprint/Fingerprint.java
deleted file mode 100644 (file)
index 32fd67c..0000000
+++ /dev/null
@@ -1,436 +0,0 @@
-/*
- * Copyright (C) https://github.com/mjwheatley/cordova-plugin-android-fingerprint-auth
- * Modifications copyright (C) 2016 Niklas Merz
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package de.niklasmerz.cordova.fingerprint;
-
-import org.apache.cordova.CordovaWebView;
-import org.apache.cordova.CallbackContext;
-import org.apache.cordova.CordovaPlugin;
-import org.apache.cordova.CordovaInterface;
-
-import android.annotation.TargetApi;
-import android.app.FragmentTransaction;
-import android.app.KeyguardManager;
-import android.content.res.Configuration;
-import android.content.res.Resources;
-import android.hardware.fingerprint.FingerprintManager;
-import android.os.Bundle;
-import android.security.keystore.KeyGenParameterSpec;
-import android.security.keystore.KeyPermanentlyInvalidatedException;
-import android.security.keystore.KeyProperties;
-import android.util.Base64;
-import android.util.DisplayMetrics;
-import android.util.Log;
-
-import org.apache.cordova.PluginResult;
-import org.json.JSONArray;
-import org.json.JSONException;
-import org.json.JSONObject;
-
-import java.io.IOException;
-import java.security.InvalidAlgorithmParameterException;
-import java.security.InvalidKeyException;
-import java.security.KeyStore;
-import java.security.KeyStoreException;
-import java.security.NoSuchAlgorithmException;
-import java.security.NoSuchProviderException;
-import java.security.UnrecoverableKeyException;
-import java.security.cert.CertificateException;
-import java.util.Locale;
-
-import javax.crypto.BadPaddingException;
-import javax.crypto.Cipher;
-import javax.crypto.IllegalBlockSizeException;
-import javax.crypto.KeyGenerator;
-import javax.crypto.NoSuchPaddingException;
-import javax.crypto.SecretKey;
-
-@TargetApi(23)
-public class Fingerprint extends CordovaPlugin {
-
-    public static final String TAG = "Fingerprint";
-    public static String packageName;
-
-    private static final String DIALOG_FRAGMENT_TAG = "FpAuthDialog";
-    private static final String ANDROID_KEY_STORE = "AndroidKeyStore";
-
-    KeyguardManager mKeyguardManager;
-    FingerprintAuthenticationDialogFragment mFragment;
-    public static KeyStore mKeyStore;
-    public static KeyGenerator mKeyGenerator;
-    public static Cipher mCipher;
-    private FingerprintManager mFingerPrintManager;
-
-    public static CallbackContext mCallbackContext;
-    public static PluginResult mPluginResult;
-
-    /**
-     * Alias for our key in the Android Key Store
-     */
-    private static String mClientId;
-    /**
-     * Used to encrypt token
-     */
-    private static String mClientSecret;
-
-    /**
-     * Options
-     */
-    private static boolean mDisableBackup = false;
-
-    /**
-     * Constructor.
-     */
-    public Fingerprint() {
-    }
-
-    /**
-     * Sets the context of the Command. This can then be used to do things like
-     * get file paths associated with the Activity.
-     *
-     * @param cordova The context of the main Activity.
-     * @param webView The CordovaWebView Cordova is running in.
-     */
-
-    public void initialize(CordovaInterface cordova, CordovaWebView webView) {
-        super.initialize(cordova, webView);
-        Log.v(TAG, "Init Fingerprint");
-        packageName = cordova.getActivity().getApplicationContext().getPackageName();
-        mPluginResult = new PluginResult(PluginResult.Status.NO_RESULT);
-
-        if (android.os.Build.VERSION.SDK_INT < 23) {
-            return;
-        }
-
-        mKeyguardManager = cordova.getActivity().getSystemService(KeyguardManager.class);
-        mFingerPrintManager = cordova.getActivity().getApplicationContext()
-                .getSystemService(FingerprintManager.class);
-
-        try {
-            mKeyGenerator = KeyGenerator.getInstance(
-                    KeyProperties.KEY_ALGORITHM_AES, ANDROID_KEY_STORE);
-            mKeyStore = KeyStore.getInstance(ANDROID_KEY_STORE);
-
-        } catch (NoSuchAlgorithmException e) {
-            throw new RuntimeException("Failed to get an instance of KeyGenerator", e);
-        } catch (NoSuchProviderException e) {
-            throw new RuntimeException("Failed to get an instance of KeyGenerator", e);
-        } catch (KeyStoreException e) {
-            throw new RuntimeException("Failed to get an instance of KeyStore", e);
-        }
-
-        try {
-            mCipher = Cipher.getInstance(KeyProperties.KEY_ALGORITHM_AES + "/"
-                    + KeyProperties.BLOCK_MODE_CBC + "/"
-                    + KeyProperties.ENCRYPTION_PADDING_PKCS7);
-        } catch (NoSuchAlgorithmException e) {
-            throw new RuntimeException("Failed to get an instance of Cipher", e);
-        } catch (NoSuchPaddingException e) {
-            throw new RuntimeException("Failed to get an instance of Cipher", e);
-        }
-    }
-
-    /**
-     * Executes the request and returns PluginResult.
-     *
-     * @param action          The action to execute.
-     * @param args            JSONArry of arguments for the plugin.
-     * @param callbackContext The callback id used when calling back into JavaScript.
-     * @return A PluginResult object with a status and message.
-     */
-    public boolean execute(final String action,
-                           JSONArray args,
-                           CallbackContext callbackContext) throws JSONException {
-        mCallbackContext = callbackContext;
-        Log.v(TAG, "Fingerprint action: " + action);
-        if (android.os.Build.VERSION.SDK_INT < 23) {
-            Log.e(TAG, "minimum SDK version 23 required");
-            mPluginResult = new PluginResult(PluginResult.Status.ERROR);
-            mCallbackContext.error("minimum SDK version 23 required");
-            mCallbackContext.sendPluginResult(mPluginResult);
-            return true;
-        }
-
-        final JSONObject arg_object = args.getJSONObject(0);
-
-        if (action.equals("authenticate")) {
-            if (!arg_object.has("clientId") || !arg_object.has("clientSecret")) {
-                mPluginResult = new PluginResult(PluginResult.Status.ERROR);
-                mCallbackContext.error("Missing required parameters");
-                mCallbackContext.sendPluginResult(mPluginResult);
-                return true;
-            }
-            mClientId = arg_object.getString("clientId");
-            mClientSecret = arg_object.getString("clientSecret");
-            if (arg_object.has("disableBackup")) {
-                mDisableBackup = arg_object.getBoolean("disableBackup");
-            }
-            // Set language
-            Resources res = cordova.getActivity().getResources();
-            // Change locale settings in the app.
-            DisplayMetrics dm = res.getDisplayMetrics();
-            Configuration conf = res.getConfiguration();
-            //Do not change locale
-            res.updateConfiguration(conf, dm);
-
-            if (isFingerprintAuthAvailable()) {
-                SecretKey key = getSecretKey();
-                boolean isCipherInit = true;
-                if (key == null) {
-                    if (createKey()) {
-                        key = getSecretKey();
-                    }
-                }
-                if (key != null && !initCipher()) {
-                    isCipherInit = false;
-                }
-                if (key != null) {
-                    cordova.getActivity().runOnUiThread(new Runnable() {
-                        public void run() {
-                            // Set up the crypto object for later. The object will be authenticated by use
-                            // of the fingerprint.
-                            mFragment = new FingerprintAuthenticationDialogFragment();
-                            Bundle bundle = new Bundle();
-                            bundle.putBoolean("disableBackup", mDisableBackup);
-                            mFragment.setArguments(bundle);
-
-                            if (initCipher()) {
-                                mFragment.setCancelable(false);
-                                // Show the fingerprint dialog. The user has the option to use the fingerprint with
-                                // crypto, or you can fall back to using a server-side verified password.
-                                mFragment.setCryptoObject(new FingerprintManager.CryptoObject(mCipher));
-                                FragmentTransaction transaction = cordova.getActivity().getFragmentManager().beginTransaction();
-                                transaction.add(mFragment, DIALOG_FRAGMENT_TAG);
-                                transaction.commitAllowingStateLoss();
-                            } else {
-                                if (!mDisableBackup) {
-                                    // This happens if the lock screen has been disabled or or a fingerprint got
-                                    // enrolled. Thus show the dialog to authenticate with their password
-                                    mFragment.setCryptoObject(new FingerprintManager
-                                            .CryptoObject(mCipher));
-                                    mFragment.setStage(FingerprintAuthenticationDialogFragment
-                                            .Stage.NEW_FINGERPRINT_ENROLLED);
-                                    FragmentTransaction transaction = cordova.getActivity().getFragmentManager().beginTransaction();
-                                    transaction.add(mFragment, DIALOG_FRAGMENT_TAG);
-                                    transaction.commitAllowingStateLoss();
-                                } else {
-                                    mCallbackContext.error("Failed to init Cipher and backup disabled.");
-                                    mPluginResult = new PluginResult(PluginResult.Status.ERROR);
-                                    mCallbackContext.sendPluginResult(mPluginResult);
-                                }
-                            }
-                        }
-                    });
-                    mPluginResult.setKeepCallback(true);
-                } else {
-                    mCallbackContext.sendPluginResult(mPluginResult);
-                }
-
-            } else {
-                mPluginResult = new PluginResult(PluginResult.Status.ERROR);
-                mCallbackContext.error("Fingerprint authentication not available");
-                mCallbackContext.sendPluginResult(mPluginResult);
-            }
-            return true;
-        } else if (action.equals("isAvailable")) {
-            if(isFingerprintAuthAvailable() && mFingerPrintManager.isHardwareDetected() && mFingerPrintManager.hasEnrolledFingerprints()){
-              mPluginResult = new PluginResult(PluginResult.Status.OK, "finger");
-              mCallbackContext.success("finger");
-            }else{
-              mPluginResult = new PluginResult(PluginResult.Status.ERROR);
-
-              if (mFingerPrintManager.isHardwareDetected() && !mFingerPrintManager.hasEnrolledFingerprints()) {
-                mCallbackContext.error("Fingerprint authentication not ready");
-              } else {
-                mCallbackContext.error("Fingerprint authentication not available");
-              }
-            }
-            mCallbackContext.sendPluginResult(mPluginResult);
-            return true;
-        }
-        return false;
-    }
-
-    private boolean isFingerprintAuthAvailable() {
-        return mFingerPrintManager.isHardwareDetected()
-                && mFingerPrintManager.hasEnrolledFingerprints();
-    }
-
-    /**
-     * Initialize the {@link Cipher} instance with the created key in the {@link #createKey()}
-     * method.
-     *
-     * @return {@code true} if initialization is successful, {@code false} if the lock screen has
-     * been disabled or reset after the key was generated, or if a fingerprint got enrolled after
-     * the key was generated.
-     */
-    private static boolean initCipher() {
-        boolean initCipher = false;
-        String errorMessage = "";
-        String initCipherExceptionErrorPrefix = "Failed to init Cipher: ";
-        try {
-            SecretKey key = getSecretKey();
-            mCipher.init(Cipher.ENCRYPT_MODE, key);
-            initCipher = true;
-        } catch (InvalidKeyException e) {
-            errorMessage = initCipherExceptionErrorPrefix + "InvalidKeyException: " + e.toString();
-            
-        }
-        if (!initCipher) {
-            Log.e(TAG, errorMessage);
-            createKey();
-        }
-        return initCipher;
-    }
-
-    private static SecretKey getSecretKey() {
-        String errorMessage = "";
-        String getSecretKeyExceptionErrorPrefix = "Failed to get SecretKey from KeyStore: ";
-        SecretKey key = null;
-        try {
-            mKeyStore.load(null);
-            key = (SecretKey) mKeyStore.getKey(mClientId, null);
-        } catch (KeyStoreException e) {
-            errorMessage = getSecretKeyExceptionErrorPrefix
-                    + "KeyStoreException: " + e.toString();;
-        } catch (CertificateException e) {
-            errorMessage = getSecretKeyExceptionErrorPrefix
-                    + "CertificateException: " + e.toString();;
-        } catch (UnrecoverableKeyException e) {
-            errorMessage = getSecretKeyExceptionErrorPrefix
-                    + "UnrecoverableKeyException: " + e.toString();;
-        } catch (IOException e) {
-            errorMessage = getSecretKeyExceptionErrorPrefix
-                    + "IOException: " + e.toString();;
-        } catch (NoSuchAlgorithmException e) {
-            errorMessage = getSecretKeyExceptionErrorPrefix
-                    + "NoSuchAlgorithmException: " + e.toString();;
-        }
-        if (key == null) {
-            Log.e(TAG, errorMessage);
-        }
-        return key;
-    }
-
-    /**
-     * Creates a symmetric key in the Android Key Store which can only be used after the user has
-     * authenticated with fingerprint.
-     */
-    public static boolean createKey() {
-        String errorMessage = "";
-        String createKeyExceptionErrorPrefix = "Failed to create key: ";
-        boolean isKeyCreated = false;
-        // The enrolling flow for fingerprint. This is where you ask the user to set up fingerprint
-        // for your flow. Use of keys is necessary if you need to know if the set of
-        // enrolled fingerprints has changed.
-        try {
-            mKeyStore.load(null);
-            // Set the alias of the entry in Android KeyStore where the key will appear
-            // and the constrains (purposes) in the constructor of the Builder
-            mKeyGenerator.init(new KeyGenParameterSpec.Builder(mClientId,
-                    KeyProperties.PURPOSE_ENCRYPT |
-                            KeyProperties.PURPOSE_DECRYPT)
-                    .setBlockModes(KeyProperties.BLOCK_MODE_CBC)
-                            // Require the user to authenticate with a fingerprint to authorize every use
-                            // of the key
-                    .setUserAuthenticationRequired(true)
-                    .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_PKCS7)
-                    .build());
-            mKeyGenerator.generateKey();
-            isKeyCreated = true;
-        } catch (NoSuchAlgorithmException e) {
-            errorMessage = createKeyExceptionErrorPrefix
-                    + "NoSuchAlgorithmException: " + e.toString();;
-        } catch (InvalidAlgorithmParameterException e) {
-            errorMessage = createKeyExceptionErrorPrefix
-                    + "InvalidAlgorithmParameterException: " + e.toString();;
-        } catch (CertificateException e) {
-            errorMessage = createKeyExceptionErrorPrefix
-                    + "CertificateException: " + e.toString();;
-        } catch (IOException e) {
-            errorMessage = createKeyExceptionErrorPrefix
-                    + "IOException: " + e.toString();;
-        }
-        if (!isKeyCreated) {
-            Log.e(TAG, errorMessage);
-            setPluginResultError(errorMessage);
-        }
-        return isKeyCreated;
-    }
-
-    public static void onAuthenticated(boolean withFingerprint) {
-        JSONObject resultJson = new JSONObject();
-        String errorMessage = "";
-        boolean createdResultJson = false;
-        try {
-
-            if (withFingerprint) {
-                // If the user has authenticated with fingerprint, verify that using cryptography and
-                // then return the encrypted token
-                byte[] encrypted = tryEncrypt();
-                resultJson.put("withFingerprint", Base64.encodeToString(encrypted, 0 /* flags */));
-            } else {
-                // Authentication happened with backup password.
-                resultJson.put("withPassword", true);
-
-                // if failed to init cipher because of InvalidKeyException, create new key
-                if (!initCipher()) {
-                    createKey();
-                }
-            }
-            createdResultJson = true;
-        } catch (BadPaddingException e) {
-            errorMessage = "Failed to encrypt the data with the generated key:" +
-                    " BadPaddingException:  " + e.getMessage();
-            Log.e(TAG, errorMessage);
-        } catch (IllegalBlockSizeException e) {
-            errorMessage = "Failed to encrypt the data with the generated key: " +
-                    "IllegalBlockSizeException: " + e.getMessage();
-            Log.e(TAG, errorMessage);
-        } catch (JSONException e) {
-            errorMessage = "Failed to set resultJson key value pair: " + e.getMessage();
-            Log.e(TAG, errorMessage);
-        }
-
-        if (createdResultJson) {
-            mCallbackContext.success(resultJson);
-            mPluginResult = new PluginResult(PluginResult.Status.OK);
-        } else {
-            mCallbackContext.error(errorMessage);
-            mPluginResult = new PluginResult(PluginResult.Status.ERROR);
-        }
-        mCallbackContext.sendPluginResult(mPluginResult);
-    }
-
-    public static void onCancelled() {
-        mCallbackContext.error("Cancelled");
-    }
-
-    /**
-     * Tries to encrypt some data with the generated key in {@link #createKey} which is
-     * only works if the user has just authenticated via fingerprint.
-     */
-    private static byte[] tryEncrypt() throws BadPaddingException, IllegalBlockSizeException {
-        return mCipher.doFinal(mClientSecret.getBytes());
-    }
-
-    public static boolean setPluginResultError(String errorMessage) {
-        mCallbackContext.error(errorMessage);
-        mPluginResult = new PluginResult(PluginResult.Status.ERROR);
-        return false;
-    }
-}
\ No newline at end of file
diff --git a/platforms/android/app/src/main/java/de/niklasmerz/cordova/fingerprint/FingerprintAuthenticationDialogFragment.java b/platforms/android/app/src/main/java/de/niklasmerz/cordova/fingerprint/FingerprintAuthenticationDialogFragment.java
deleted file mode 100644 (file)
index 54fb28d..0000000
+++ /dev/null
@@ -1,268 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- * Modifications copyright (C) 2016 Niklas Merz
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package de.niklasmerz.cordova.fingerprint;
-
-import android.app.DialogFragment;
-import android.app.KeyguardManager;
-import android.content.Context;
-import android.content.DialogInterface;
-import android.content.Intent;
-import android.content.SharedPreferences;
-import android.hardware.fingerprint.FingerprintManager;
-import android.os.Bundle;
-import android.util.Log;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.view.inputmethod.InputMethodManager;
-import android.widget.Button;
-import android.widget.ImageView;
-import android.widget.TextView;
-import android.widget.Toast;
-
-/**
- * A dialog which uses fingerprint APIs to authenticate the user, and falls back to password
- * authentication if fingerprint is not available.
- */
-public class FingerprintAuthenticationDialogFragment extends DialogFragment
-        implements FingerprintUiHelper.Callback {
-
-    private static final String TAG = "FingerprintAuthDialog";
-    private static final int REQUEST_CODE_CONFIRM_DEVICE_CREDENTIALS = 1;
-
-    private Button mCancelButton;
-    private Button mSecondDialogButton;
-    private View mFingerprintContent;
-
-    private Stage mStage = Stage.FINGERPRINT;
-
-    private KeyguardManager mKeyguardManager;
-    private FingerprintManager.CryptoObject mCryptoObject;
-    private FingerprintUiHelper mFingerprintUiHelper;
-    FingerprintUiHelper.FingerprintUiHelperBuilder mFingerprintUiHelperBuilder;
-
-    boolean disableBackup;
-
-    public FingerprintAuthenticationDialogFragment() {
-    }
-
-    @Override
-    public void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-
-        // Do not create a new Fragment when the Activity is re-created such as orientation changes.
-        setRetainInstance(true);
-        setStyle(DialogFragment.STYLE_NORMAL, android.R.style.Theme_Material_Light_Dialog);
-
-        mKeyguardManager = (KeyguardManager) getContext().getSystemService(Context.KEYGUARD_SERVICE);
-        mFingerprintUiHelperBuilder = new FingerprintUiHelper.FingerprintUiHelperBuilder(
-                getContext(), getContext().getSystemService(FingerprintManager.class));
-
-    }
-
-    @Override
-    public View onCreateView(LayoutInflater inflater, ViewGroup container,
-                             Bundle savedInstanceState) {
-        Bundle args = getArguments();
-        disableBackup = args.getBoolean("disableBackup");
-        Log.d(TAG, "disableBackup: " + disableBackup);
-
-        int fingerprint_auth_dialog_title_id = getResources()
-                .getIdentifier("fingerprint_auth_dialog_title", "string",
-                        Fingerprint.packageName);
-        getDialog().setTitle(getString(fingerprint_auth_dialog_title_id));
-        int fingerprint_dialog_container_id = getResources()
-                .getIdentifier("fingerprint_dialog_container", "layout",
-                        Fingerprint.packageName);
-        View v = inflater.inflate(fingerprint_dialog_container_id, container, false);
-        int cancel_button_id = getResources()
-                .getIdentifier("cancel_button", "id", Fingerprint.packageName);
-        mCancelButton = (Button) v.findViewById(cancel_button_id);
-        mCancelButton.setOnClickListener(new View.OnClickListener() {
-            @Override
-            public void onClick(View view) {
-                Fingerprint.onCancelled();
-                dismissAllowingStateLoss();
-            }
-        });
-
-        int second_dialog_button_id = getResources()
-                .getIdentifier("second_dialog_button", "id", Fingerprint.packageName);
-        mSecondDialogButton = (Button) v.findViewById(second_dialog_button_id);
-        if (disableBackup) {
-            mSecondDialogButton.setVisibility(View.GONE);
-        }
-        mSecondDialogButton.setOnClickListener(new View.OnClickListener() {
-            @Override
-            public void onClick(View view) {
-                goToBackup();
-            }
-        });
-        int fingerprint_container_id = getResources()
-                .getIdentifier("fingerprint_container", "id", Fingerprint.packageName);
-        mFingerprintContent = v.findViewById(fingerprint_container_id);
-
-        int new_fingerprint_enrolled_description_id = getResources()
-                .getIdentifier("new_fingerprint_enrolled_description", "id",
-                        Fingerprint.packageName);
-
-        int fingerprint_icon_id = getResources()
-                .getIdentifier("fingerprint_icon", "id", Fingerprint.packageName);
-        int fingerprint_status_id = getResources()
-                .getIdentifier("fingerprint_status", "id", Fingerprint.packageName);
-        mFingerprintUiHelper = mFingerprintUiHelperBuilder.build(
-                (ImageView) v.findViewById(fingerprint_icon_id),
-                (TextView) v.findViewById(fingerprint_status_id), this);
-        updateStage();
-
-        // If fingerprint authentication is not available, switch immediately to the backup
-        // (password) screen.
-        if (!mFingerprintUiHelper.isFingerprintAuthAvailable()) {
-            goToBackup();
-        }
-        return v;
-    }
-
-
-    @Override
-    public void onResume() {
-        super.onResume();
-        if (mStage == Stage.FINGERPRINT) {
-            mFingerprintUiHelper.startListening(mCryptoObject);
-        }
-    }
-
-    public void setStage(Stage stage) {
-        mStage = stage;
-    }
-
-    @Override
-    public void onPause() {
-        super.onPause();
-        mFingerprintUiHelper.stopListening();
-    }
-
-    /**
-     * Sets the crypto object to be passed in when authenticating with fingerprint.
-     */
-    public void setCryptoObject(FingerprintManager.CryptoObject cryptoObject) {
-        mCryptoObject = cryptoObject;
-    }
-
-    /**
-     * Switches to backup (password) screen. This either can happen when fingerprint is not
-     * available or the user chooses to use the password authentication method by pressing the
-     * button. This can also happen when the user had too many fingerprint attempts.
-     */
-    private void goToBackup() {
-        if(disableBackup)
-        {
-            Fingerprint.onCancelled(); 
-            dismissAllowingStateLoss();
-        }
-        else{
-            mStage = Stage.BACKUP;
-            updateStage();
-        }
-    }
-
-    private void updateStage() {
-        int cancel_id = getResources()
-                .getIdentifier("fingerprint_cancel", "string", Fingerprint.packageName);
-        switch (mStage) {
-            case FINGERPRINT:
-                mCancelButton.setText(cancel_id);
-                int use_backup_id = getResources()
-                        .getIdentifier("fingerprint_use_backup", "string", Fingerprint.packageName);
-                mSecondDialogButton.setText(use_backup_id);
-                mFingerprintContent.setVisibility(View.VISIBLE);
-                break;
-            case NEW_FINGERPRINT_ENROLLED:
-                // Intentional fall through
-            case BACKUP:
-                if (mStage == Stage.NEW_FINGERPRINT_ENROLLED) {
-
-                }
-                if (!mKeyguardManager.isKeyguardSecure()) {
-                    // Show a message that the user hasn't set up a lock screen.
-                    int secure_lock_screen_required_id = getResources()
-                            .getIdentifier("secure_lock_screen_required", "string",
-                                    Fingerprint.packageName);
-                    Toast.makeText(getContext(),
-                            getString(secure_lock_screen_required_id),
-                            Toast.LENGTH_LONG).show();
-                    return;
-                }
-                showAuthenticationScreen();
-                break;
-        }
-    }
-
-    private void showAuthenticationScreen() {
-        // Create the Confirm Credentials screen. You can customize the title and description. Or
-        // we will provide a generic one for you if you leave it null
-        Intent intent = mKeyguardManager.createConfirmDeviceCredentialIntent(null, null);
-        if (intent != null) {
-            startActivityForResult(intent, REQUEST_CODE_CONFIRM_DEVICE_CREDENTIALS);
-        }
-    }
-
-    @Override
-    public void onActivityResult(int requestCode, int resultCode, Intent data) {
-        if (requestCode == REQUEST_CODE_CONFIRM_DEVICE_CREDENTIALS) {
-            // Challenge completed, proceed with using cipher
-            if (resultCode == getActivity().RESULT_OK) {
-                Fingerprint.onAuthenticated(false /* used backup */);
-            } else {
-                // The user canceled or didn’t complete the lock screen
-                // operation. Go to error/cancellation flow.
-                Fingerprint.onCancelled();
-            }
-            dismissAllowingStateLoss();
-        }
-    }
-
-    @Override
-    public void onAuthenticated() {
-        // Callback from FingerprintUiHelper. Let the activity know that authentication was
-        // successful.
-        Fingerprint.onAuthenticated(true /* withFingerprint */);
-        dismissAllowingStateLoss();
-    }
-
-    @Override
-    public void onError() {
-        if(this.getActivity() != null)
-            goToBackup();
-    }
-
-    @Override
-    public void onCancel(DialogInterface dialog) {
-        super.onCancel(dialog);
-        Fingerprint.onCancelled();
-    }
-
-    /**
-     * Enumeration to indicate which authentication method the user is trying to authenticate with.
-     */
-    public enum Stage {
-        FINGERPRINT,
-        NEW_FINGERPRINT_ENROLLED,
-        BACKUP
-    }
-}
diff --git a/platforms/android/app/src/main/java/de/niklasmerz/cordova/fingerprint/FingerprintUiHelper.java b/platforms/android/app/src/main/java/de/niklasmerz/cordova/fingerprint/FingerprintUiHelper.java
deleted file mode 100644 (file)
index e1402c5..0000000
+++ /dev/null
@@ -1,189 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- * Modifications copyright (C) 2016 Niklas Merz
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package de.niklasmerz.cordova.fingerprint;
-
-import android.annotation.TargetApi;
-import android.content.Context;
-import android.hardware.fingerprint.FingerprintManager;
-import android.os.CancellationSignal;
-import android.widget.ImageView;
-import android.widget.TextView;
-
-
-/**
- * Small helper class to manage text/icon around fingerprint authentication UI.
- */
-@TargetApi(23)
-public class FingerprintUiHelper extends FingerprintManager.AuthenticationCallback {
-
-    static final long ERROR_TIMEOUT_MILLIS = 1600;
-    static final long SUCCESS_DELAY_MILLIS = 1300;
-
-    private final Context mContext;
-    private final FingerprintManager mFingerprintManager;
-    private final ImageView mIcon;
-    private final TextView mErrorTextView;
-    private final Callback mCallback;
-    private CancellationSignal mCancellationSignal;
-
-    boolean mSelfCancelled;
-
-    /**
-     * Builder class for {@link FingerprintUiHelper} in which injected fields from Dagger
-     * holds its fields and takes other arguments in the {@link #build} method.
-     */
-    public static class FingerprintUiHelperBuilder {
-        private final FingerprintManager mFingerPrintManager;
-        private final Context mContext;
-
-        public FingerprintUiHelperBuilder(Context context, FingerprintManager fingerprintManager) {
-            mFingerPrintManager = fingerprintManager;
-            mContext = context;
-        }
-
-        public FingerprintUiHelper build(ImageView icon, TextView errorTextView, Callback callback) {
-            return new FingerprintUiHelper(mContext, mFingerPrintManager, icon, errorTextView,
-                    callback);
-        }
-    }
-
-    /**
-     * Constructor for {@link FingerprintUiHelper}. This method is expected to be called from
-     * only the {@link FingerprintUiHelperBuilder} class.
-     */
-    private FingerprintUiHelper(Context context, FingerprintManager fingerprintManager,
-            ImageView icon, TextView errorTextView, Callback callback) {
-        mFingerprintManager = fingerprintManager;
-        mIcon = icon;
-        mErrorTextView = errorTextView;
-        mCallback = callback;
-        mContext = context;
-    }
-
-    public boolean isFingerprintAuthAvailable() {
-        return mFingerprintManager.isHardwareDetected()
-                && mFingerprintManager.hasEnrolledFingerprints();
-    }
-
-    public void startListening(FingerprintManager.CryptoObject cryptoObject) {
-        if (!isFingerprintAuthAvailable()) {
-            return;
-        }
-        mCancellationSignal = new CancellationSignal();
-        mSelfCancelled = false;
-        mFingerprintManager
-                .authenticate(cryptoObject, mCancellationSignal, 0 /* flags */, this, null);
-
-        int ic_fp_40px_id = mContext.getResources()
-                .getIdentifier("ic_fp_40px", "drawable", Fingerprint.packageName);
-        mIcon.setImageResource(ic_fp_40px_id);
-    }
-
-    public void stopListening() {
-        if (mCancellationSignal != null) {
-            mSelfCancelled = true;
-            mCancellationSignal.cancel();
-            mCancellationSignal = null;
-        }
-    }
-
-    @Override
-    public void onAuthenticationError(int errMsgId, CharSequence errString) {
-        if (!mSelfCancelled) {
-            showError(errString);
-            mIcon.postDelayed(new Runnable() {
-                @Override
-                public void run() {
-                    mCallback.onError();
-                }
-            }, ERROR_TIMEOUT_MILLIS);
-        }
-    }
-
-    @Override
-    public void onAuthenticationHelp(int helpMsgId, CharSequence helpString) {
-        showError(helpString);
-    }
-
-    @Override
-    public void onAuthenticationFailed() {
-        int fingerprint_not_recognized_id = mContext.getResources()
-                .getIdentifier("fingerprint_not_recognized", "string", Fingerprint.packageName);
-        showError(mIcon.getResources().getString(
-                fingerprint_not_recognized_id));
-    }
-
-    @Override
-    public void onAuthenticationSucceeded(FingerprintManager.AuthenticationResult result) {
-        mErrorTextView.removeCallbacks(mResetErrorTextRunnable);
-        int ic_fingerprint_success_id = mContext.getResources()
-                .getIdentifier("ic_fingerprint_success", "drawable", Fingerprint.packageName);
-        mIcon.setImageResource(ic_fingerprint_success_id);
-        int success_color_id = mContext.getResources()
-                .getIdentifier("success_color", "color", Fingerprint.packageName);
-        mErrorTextView.setTextColor(
-                mErrorTextView.getResources().getColor(success_color_id, null));
-        int fingerprint_success_id = mContext.getResources()
-                .getIdentifier("fingerprint_success", "string", Fingerprint.packageName);
-        mErrorTextView.setText(
-                mErrorTextView.getResources().getString(fingerprint_success_id));
-        mIcon.postDelayed(new Runnable() {
-            @Override
-            public void run() {
-                mCallback.onAuthenticated();
-            }
-        }, SUCCESS_DELAY_MILLIS);
-    }
-
-    private void showError(CharSequence error) {
-        int ic_fingerprint_error_id = mContext.getResources()
-                .getIdentifier("ic_fingerprint_error", "drawable", Fingerprint.packageName);
-        mIcon.setImageResource(ic_fingerprint_error_id);
-        mErrorTextView.setText(error);
-        int warning_color_id = mContext.getResources()
-                .getIdentifier("warning_color", "color", Fingerprint.packageName);
-        mErrorTextView.setTextColor(
-                mErrorTextView.getResources().getColor(warning_color_id, null));
-        mErrorTextView.removeCallbacks(mResetErrorTextRunnable);
-        mErrorTextView.postDelayed(mResetErrorTextRunnable, ERROR_TIMEOUT_MILLIS);
-    }
-
-    Runnable mResetErrorTextRunnable = new Runnable() {
-        @Override
-        public void run() {
-            int hint_color_id = mContext.getResources()
-                    .getIdentifier("hint_color", "color", Fingerprint.packageName);
-            mErrorTextView.setTextColor(
-                    mErrorTextView.getResources().getColor(hint_color_id, null));
-            int fingerprint_hint_id = mContext.getResources()
-                    .getIdentifier("fingerprint_hint", "string", Fingerprint.packageName);
-            mErrorTextView.setText(
-                    mErrorTextView.getResources().getString(fingerprint_hint_id));
-            int ic_fp_40px_id = mContext.getResources()
-                    .getIdentifier("ic_fp_40px", "drawable", Fingerprint.packageName);
-            mIcon.setImageResource(ic_fp_40px_id);
-        }
-    };
-
-    public interface Callback {
-
-        void onAuthenticated();
-
-        void onError();
-    }
-}
diff --git a/platforms/android/app/src/main/res/drawable-hdpi/ic_fp_40px.png b/platforms/android/app/src/main/res/drawable-hdpi/ic_fp_40px.png
deleted file mode 100644 (file)
index 48ebd8a..0000000
Binary files a/platforms/android/app/src/main/res/drawable-hdpi/ic_fp_40px.png and /dev/null differ
index 1769fc5..a79c7cf 100644 (file)
Binary files a/platforms/android/app/src/main/res/drawable-hdpi/icon.png and b/platforms/android/app/src/main/res/drawable-hdpi/icon.png differ
index 1769fc5..24166c6 100644 (file)
Binary files a/platforms/android/app/src/main/res/drawable-ldpi/icon.png and b/platforms/android/app/src/main/res/drawable-ldpi/icon.png differ
diff --git a/platforms/android/app/src/main/res/drawable-mdpi/ic_fp_40px.png b/platforms/android/app/src/main/res/drawable-mdpi/ic_fp_40px.png
deleted file mode 100644 (file)
index 122f442..0000000
Binary files a/platforms/android/app/src/main/res/drawable-mdpi/ic_fp_40px.png and /dev/null differ
index 92a3334..613d8e7 100644 (file)
Binary files a/platforms/android/app/src/main/res/drawable-mdpi/icon.png and b/platforms/android/app/src/main/res/drawable-mdpi/icon.png differ
diff --git a/platforms/android/app/src/main/res/drawable-nodpi/android_robot.png b/platforms/android/app/src/main/res/drawable-nodpi/android_robot.png
deleted file mode 100644 (file)
index 40bf934..0000000
Binary files a/platforms/android/app/src/main/res/drawable-nodpi/android_robot.png and /dev/null differ
diff --git a/platforms/android/app/src/main/res/drawable-xhdpi/ic_fp_40px.png b/platforms/android/app/src/main/res/drawable-xhdpi/ic_fp_40px.png
deleted file mode 100644 (file)
index e1c9590..0000000
Binary files a/platforms/android/app/src/main/res/drawable-xhdpi/ic_fp_40px.png and /dev/null differ
index 4f54d23..1737ab8 100644 (file)
Binary files a/platforms/android/app/src/main/res/drawable-xhdpi/icon.png and b/platforms/android/app/src/main/res/drawable-xhdpi/icon.png differ
diff --git a/platforms/android/app/src/main/res/drawable-xxhdpi/ic_fp_40px.png b/platforms/android/app/src/main/res/drawable-xxhdpi/ic_fp_40px.png
deleted file mode 100644 (file)
index f7e8724..0000000
Binary files a/platforms/android/app/src/main/res/drawable-xxhdpi/ic_fp_40px.png and /dev/null differ
index ea73508..a8c7b45 100644 (file)
Binary files a/platforms/android/app/src/main/res/drawable-xxhdpi/icon.png and b/platforms/android/app/src/main/res/drawable-xxhdpi/icon.png differ
diff --git a/platforms/android/app/src/main/res/drawable-xxxhdpi/ic_fp_40px.png b/platforms/android/app/src/main/res/drawable-xxxhdpi/ic_fp_40px.png
deleted file mode 100644 (file)
index 0fb8545..0000000
Binary files a/platforms/android/app/src/main/res/drawable-xxxhdpi/ic_fp_40px.png and /dev/null differ
index 8b754c8..5b33488 100644 (file)
Binary files a/platforms/android/app/src/main/res/drawable-xxxhdpi/icon.png and b/platforms/android/app/src/main/res/drawable-xxxhdpi/icon.png differ
diff --git a/platforms/android/app/src/main/res/drawable/ic_fingerprint_error.xml b/platforms/android/app/src/main/res/drawable/ic_fingerprint_error.xml
deleted file mode 100644 (file)
index be46116..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  ~ Copyright (C) 2015 The Android Open Source Project
-  ~
-  ~ Licensed under the Apache License, Version 2.0 (the "License");
-  ~ you may not use this file except in compliance with the License.
-  ~ You may obtain a copy of the License at
-  ~
-  ~      http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~ Unless required by applicable law or agreed to in writing, software
-  ~ distributed under the License is distributed on an "AS IS" BASIS,
-  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  ~ See the License for the specific language governing permissions and
-  ~ limitations under the License
-  -->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:width="40.0dp"
-        android:height="40.0dp"
-        android:viewportWidth="40.0"
-        android:viewportHeight="40.0">
-    <path
-        android:pathData="M20.0,0.0C8.96,0.0 0.0,8.95 0.0,20.0s8.96,20.0 20.0,20.0c11.04,0.0 20.0,-8.95 20.0,-20.0S31.04,0.0 20.0,0.0z"
-        android:fillColor="#F4511E"/>
-    <path
-        android:pathData="M21.33,29.33l-2.67,0.0l0.0,-2.67l2.67,0.0L21.33,29.33zM21.33,22.67l-2.67,0.0l0.0,-12.0l2.67,0.0L21.33,22.67z"
-        android:fillColor="#FFFFFF"/>
-</vector>
diff --git a/platforms/android/app/src/main/res/drawable/ic_fingerprint_success.xml b/platforms/android/app/src/main/res/drawable/ic_fingerprint_success.xml
deleted file mode 100644 (file)
index 261f3e7..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  ~ Copyright (C) 2015 The Android Open Source Project
-  ~
-  ~ Licensed under the Apache License, Version 2.0 (the "License");
-  ~ you may not use this file except in compliance with the License.
-  ~ You may obtain a copy of the License at
-  ~
-  ~      http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~ Unless required by applicable law or agreed to in writing, software
-  ~ distributed under the License is distributed on an "AS IS" BASIS,
-  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  ~ See the License for the specific language governing permissions and
-  ~ limitations under the License
-  -->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:width="40.0dp"
-        android:height="40.0dp"
-        android:viewportWidth="40.0"
-        android:viewportHeight="40.0">
-    <path
-        android:pathData="M20.0,20.0m-20.0,0.0a20.0,20.0 0.0,1.0 1.0,40.0 0.0a20.0,20.0 0.0,1.0 1.0,-40.0 0.0"
-        android:fillColor="#009688"/>
-    <path
-        android:pathData="M11.2,21.41l1.63,-1.619999 4.17,4.169998 10.59,-10.589999 1.619999,1.63 -12.209999,12.209999z"
-        android:fillColor="#FFFFFF"/>
-</vector>
diff --git a/platforms/android/app/src/main/res/layout/biometric_activity.xml b/platforms/android/app/src/main/res/layout/biometric_activity.xml
new file mode 100644 (file)
index 0000000..5708761
--- /dev/null
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  Copyright 2019 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent" android:layout_height="match_parent">
+
+</FrameLayout>
\ No newline at end of file
diff --git a/platforms/android/app/src/main/res/layout/fingerprint_dialog_container.xml b/platforms/android/app/src/main/res/layout/fingerprint_dialog_container.xml
deleted file mode 100644 (file)
index 0c6face..0000000
+++ /dev/null
@@ -1,61 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  ~ Copyright (C) 2015 The Android Open Source Project
-  ~
-  ~ Licensed under the Apache License, Version 2.0 (the "License");
-  ~ you may not use this file except in compliance with the License.
-  ~ You may obtain a copy of the License at
-  ~
-  ~      http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~ Unless required by applicable law or agreed to in writing, software
-  ~ distributed under the License is distributed on an "AS IS" BASIS,
-  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  ~ See the License for the specific language governing permissions and
-  ~ limitations under the License
-  -->
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_width="match_parent"
-    android:layout_height="match_parent"
-    android:orientation="vertical">
-
-    <FrameLayout
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content">
-
-        <include layout="@layout/fingerprint_dialog_content" />
-
-    </FrameLayout>
-
-    <LinearLayout
-        android:id="@+id/buttonPanel"
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:orientation="horizontal"
-        android:paddingStart="12dp"
-        android:paddingEnd="12dp"
-        android:paddingTop="4dp"
-        android:paddingBottom="4dp"
-        android:gravity="bottom"
-        style="?android:attr/buttonBarStyle">
-
-        <Space
-            android:id="@+id/spacer"
-            android:layout_width="0dp"
-            android:layout_height="0dp"
-            android:layout_weight="1"
-            android:visibility="invisible" />
-        <Button
-            android:id="@+id/cancel_button"
-            style="?android:attr/buttonBarNegativeButtonStyle"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"/>
-
-        <Button
-            android:id="@+id/second_dialog_button"
-            style="?android:attr/buttonBarPositiveButtonStyle"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"/>
-    </LinearLayout>
-
-</LinearLayout>
\ No newline at end of file
diff --git a/platforms/android/app/src/main/res/layout/fingerprint_dialog_content.xml b/platforms/android/app/src/main/res/layout/fingerprint_dialog_content.xml
deleted file mode 100644 (file)
index 3929eba..0000000
+++ /dev/null
@@ -1,58 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  ~ Copyright (C) 2015 The Android Open Source Project
-  ~
-  ~ Licensed under the Apache License, Version 2.0 (the "License");
-  ~ you may not use this file except in compliance with the License.
-  ~ You may obtain a copy of the License at
-  ~
-  ~      http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~ Unless required by applicable law or agreed to in writing, software
-  ~ distributed under the License is distributed on an "AS IS" BASIS,
-  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  ~ See the License for the specific language governing permissions and
-  ~ limitations under the License
-  -->
-<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    android:id="@+id/fingerprint_container"
-    android:layout_width="match_parent"
-    android:layout_height="match_parent"
-    android:paddingBottom="8dp"
-    android:paddingStart="24dp"
-    android:paddingEnd="24dp"
-    android:paddingTop="16dp">
-
-    <TextView
-        android:id="@+id/fingerprint_description"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_alignParentStart="true"
-        android:layout_alignParentTop="true"
-        android:text="@string/fingerprint_description"
-        android:textAppearance="@android:style/TextAppearance.Material.Subhead"
-        android:textColor="?android:attr/textColorSecondary"/>
-
-
-    <ImageView
-        android:id="@+id/fingerprint_icon"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_alignParentStart="true"
-        android:layout_below="@+id/fingerprint_description"
-        android:layout_marginTop="20dp"
-        android:src="@drawable/ic_fp_40px" />
-
-    <TextView
-        android:id="@+id/fingerprint_status"
-        style="@android:style/TextAppearance.Material.Body1"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_alignBottom="@+id/fingerprint_icon"
-        android:layout_alignTop="@+id/fingerprint_icon"
-        android:layout_marginStart="16dp"
-        android:layout_toEndOf="@+id/fingerprint_icon"
-        android:gravity="center_vertical"
-        android:text="@string/fingerprint_hint"
-        android:textColor="@color/hint_color" />
-</RelativeLayout>
\ No newline at end of file
index 1769fc5..a79c7cf 100644 (file)
Binary files a/platforms/android/app/src/main/res/mipmap-hdpi-v26/ic_launcher_foreground.png and b/platforms/android/app/src/main/res/mipmap-hdpi-v26/ic_launcher_foreground.png differ
index 1769fc5..a79c7cf 100644 (file)
Binary files a/platforms/android/app/src/main/res/mipmap-hdpi/ic_launcher.png and b/platforms/android/app/src/main/res/mipmap-hdpi/ic_launcher.png differ
index 530c91d..24166c6 100644 (file)
Binary files a/platforms/android/app/src/main/res/mipmap-ldpi-v26/ic_launcher_foreground.png and b/platforms/android/app/src/main/res/mipmap-ldpi-v26/ic_launcher_foreground.png differ
index 530c91d..24166c6 100644 (file)
Binary files a/platforms/android/app/src/main/res/mipmap-ldpi/ic_launcher.png and b/platforms/android/app/src/main/res/mipmap-ldpi/ic_launcher.png differ
index 92a3334..613d8e7 100644 (file)
Binary files a/platforms/android/app/src/main/res/mipmap-mdpi-v26/ic_launcher_foreground.png and b/platforms/android/app/src/main/res/mipmap-mdpi-v26/ic_launcher_foreground.png differ
index 92a3334..613d8e7 100644 (file)
Binary files a/platforms/android/app/src/main/res/mipmap-mdpi/ic_launcher.png and b/platforms/android/app/src/main/res/mipmap-mdpi/ic_launcher.png differ
index 4f54d23..1737ab8 100644 (file)
Binary files a/platforms/android/app/src/main/res/mipmap-xhdpi-v26/ic_launcher_foreground.png and b/platforms/android/app/src/main/res/mipmap-xhdpi-v26/ic_launcher_foreground.png differ
index 4f54d23..1737ab8 100644 (file)
Binary files a/platforms/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png and b/platforms/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png differ
index ea73508..a8c7b45 100644 (file)
Binary files a/platforms/android/app/src/main/res/mipmap-xxhdpi-v26/ic_launcher_foreground.png and b/platforms/android/app/src/main/res/mipmap-xxhdpi-v26/ic_launcher_foreground.png differ
index ea73508..a8c7b45 100644 (file)
Binary files a/platforms/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png and b/platforms/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png differ
index 8b754c8..5b33488 100644 (file)
Binary files a/platforms/android/app/src/main/res/mipmap-xxxhdpi-v26/ic_launcher_foreground.png and b/platforms/android/app/src/main/res/mipmap-xxxhdpi-v26/ic_launcher_foreground.png differ
index 8b754c8..5b33488 100644 (file)
Binary files a/platforms/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png and b/platforms/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png differ
diff --git a/platforms/android/app/src/main/res/values-da/fpauth-strings.xml b/platforms/android/app/src/main/res/values-da/fpauth-strings.xml
deleted file mode 100644 (file)
index 346666f..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<resources>
-    <string name="fingerprint_cancel">Annuller</string>
-    <string name="fingerprint_use_backup">Brug backup</string>
-    <string name="fingerprint_auth_dialog_title">Fingeraftryk Login</string>
-    <string name="fingerprint_ok">Ok</string>
-    <string name="fingerprint_description">Bekræft fingeraftryk for at fortsætte</string>
-    <string name="fingerprint_hint">Rør sensor</string>
-    <string name="fingerprint_not_recognized">Fingeraftryk ikke genkendt. Prøv igen.</string>
-    <string name="fingerprint_success">Fingeraftryk godkendt</string>
-    <string name="new_fingerprint_enrolled_description">Et nyt fingeraftryk blev tilføjet til denne enhed så din adgangskode er krævet.</string>
-    <string name="secure_lock_screen_required">Sikring af skærmlås krævet!</string>
-</resources>
diff --git a/platforms/android/app/src/main/res/values-de/fpauth-strings.xml b/platforms/android/app/src/main/res/values-de/fpauth-strings.xml
deleted file mode 100644 (file)
index d5b6bd2..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  ~ Copyright (C) 2015 The Android Open Source Project
-  ~
-  ~ Licensed under the Apache License, Version 2.0 (the "License");
-  ~ you may not use this file except in compliance with the License.
-  ~ You may obtain a copy of the License at
-  ~
-  ~      http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~ Unless required by applicable law or agreed to in writing, software
-  ~ distributed under the License is distributed on an "AS IS" BASIS,
-  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  ~ See the License for the specific language governing permissions and
-  ~ limitations under the License
-  -->
-<resources>
-    <string name="fingerprint_cancel">Abbrechen</string>
-    <string name="fingerprint_use_backup">Passwort</string>
-    <string name="fingerprint_auth_dialog_title">Authentifizierung</string>
-    <string name="fingerprint_ok">OK</string>
-    <string name="fingerprint_description">Fingerabdruck bestätigen</string>
-    <string name="fingerprint_hint">Fingerabdrucksensor</string>
-    <string name="fingerprint_not_recognized">Fingerabdruck nicht erkannt. Versuchen Sie es erneut</string>
-    <string name="fingerprint_success">Authentifiziert</string>
-    <string name="new_fingerprint_enrolled_description">Ein neuer Fingerabdruck wurde gespeichert. Bitte geben Sie ihr Passwort ein.</string>
-    <string name="secure_lock_screen_required">Passwortgeschützter Sperrbildschirm benötigt</string>
-</resources>
diff --git a/platforms/android/app/src/main/res/values-el/fpauth-strings.xml b/platforms/android/app/src/main/res/values-el/fpauth-strings.xml
deleted file mode 100644 (file)
index 1dcfcdb..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<resources>
-    <string name="fingerprint_cancel">Ακύρωση</string>
-    <string name="fingerprint_use_backup">Χρήση αρχείου</string>
-    <string name="fingerprint_auth_dialog_title">Ελεγχος αποτυπώματος</string>
-    <string name="fingerprint_ok">Ok</string>
-    <string name="fingerprint_description">Επιβεβαίωση αποτυπώματος</string>
-    <string name="fingerprint_hint">Αιθηστήρας αφής</string>
-    <string name="fingerprint_not_recognized">Σφάλμα. Προσπαθήστε ξανά</string>
-    <string name="fingerprint_success">Σωστό αποτύπωμα</string>
-    <string name="new_fingerprint_enrolled_description">Νεο αποτύπωμα προστέθηκε , απαιτείται ο κωδικός σας.</string>
-    <string name="secure_lock_screen_required">Απαιτείται κλειδωμα οθόνης</string>
-</resources>
diff --git a/platforms/android/app/src/main/res/values-es/fpauth-strings.xml b/platforms/android/app/src/main/res/values-es/fpauth-strings.xml
deleted file mode 100644 (file)
index 25bdbb2..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  ~ Copyright (C) 2015 The Android Open Source Project
-  ~
-  ~ Licensed under the Apache License, Version 2.0 (the "License");
-  ~ you may not use this file except in compliance with the License.
-  ~ You may obtain a copy of the License at
-  ~
-  ~      http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~ Unless required by applicable law or agreed to in writing, software
-  ~ distributed under the License is distributed on an "AS IS" BASIS,
-  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  ~ See the License for the specific language governing permissions and
-  ~ limitations under the License
-  -->
-<resources>
-    <string name="fingerprint_cancel">Cancelar</string>
-    <string name="fingerprint_use_backup">El Respaldo</string>
-    <string name="fingerprint_auth_dialog_title">Autenticación de Huellas Digitales</string>
-    <string name="fingerprint_ok">De Acuerdo</string>
-    <string name="fingerprint_description">Confirmar la huella digital para continuar</string>
-    <string name="fingerprint_hint">Sensor tactil</string>
-    <string name="fingerprint_not_recognized">No se reconoce la huella digital. Inténtalo de nuevo.</string>
-    <string name="fingerprint_success">Reconocido de huella dactilar</string>
-    <string name="new_fingerprint_enrolled_description">Una nueva huella digital fue agregada a este dispositivo, por lo que se requiere la contraseña.</string>
-    <string name="secure_lock_screen_required">¡Requiere pantalla de bloqueo seguro!</string>
-</resources>
diff --git a/platforms/android/app/src/main/res/values-fr/fpauth-strings.xml b/platforms/android/app/src/main/res/values-fr/fpauth-strings.xml
deleted file mode 100644 (file)
index 4b9d3eb..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  ~ Copyright (C) 2015 The Android Open Source Project
-  ~
-  ~ Licensed under the Apache License, Version 2.0 (the "License");
-  ~ you may not use this file except in compliance with the License.
-  ~ You may obtain a copy of the License at
-  ~
-  ~      http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~ Unless required by applicable law or agreed to in writing, software
-  ~ distributed under the License is distributed on an "AS IS" BASIS,
-  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  ~ See the License for the specific language governing permissions and
-  ~ limitations under the License
-  -->
-<resources>
-    <string name="fingerprint_cancel">Annuler</string>
-    <string name="fingerprint_use_backup">Utiliser la sauvegarde</string>
-    <string name="fingerprint_auth_dialog_title">Authentification par empreinte digitale</string>
-    <string name="fingerprint_ok">Ok</string>
-    <string name="fingerprint_description">Confirmer l\'empreinte pour continuer</string>
-    <string name="fingerprint_hint">Toucher le capteur</string>
-    <string name="fingerprint_not_recognized">Empreinte non reconnue. Essayer à nouveau.</string>
-    <string name="fingerprint_success">Empreinte reconnue</string>
-    <string name="new_fingerprint_enrolled_description">Une nouvelle empreinte digitale a été ajoutée à ce dispositif, de sorte que votre mot de passe est nécessaire.</string>
-    <string name="secure_lock_screen_required">Écran de verrouillage sécurisé nécessaire!</string>
-</resources>
diff --git a/platforms/android/app/src/main/res/values-it/fpauth-strings.xml b/platforms/android/app/src/main/res/values-it/fpauth-strings.xml
deleted file mode 100644 (file)
index a226ff8..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<resources>
-    <string name="fingerprint_cancel">Cancella</string>
-    <string name="fingerprint_use_backup">Usa backup</string>
-    <string name="fingerprint_auth_dialog_title">Autenticazione impronta digitale</string>
-    <string name="fingerprint_ok">Ok</string>
-    <string name="fingerprint_description">Conferma l\'impronta digitale per continuare</string>
-    <string name="fingerprint_hint">Sensore Touch</string>
-    <string name="fingerprint_not_recognized">Impronta digitale non riconosciuta. Riprova.</string>
-    <string name="fingerprint_success">Impronta digitale riconosciuta</string>
-    <string name="new_fingerprint_enrolled_description">Una nuova impronta è stata aggiunta a questo dispositivo, quindi è necessaria la tua password</string>
-    <string name="secure_lock_screen_required">Blocco schermo richiesto!</string>
-</resources>
diff --git a/platforms/android/app/src/main/res/values-nl/fpauth-strings.xml b/platforms/android/app/src/main/res/values-nl/fpauth-strings.xml
deleted file mode 100644 (file)
index e44731c..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-<resources>
-    <string name="fingerprint_cancel">Annuleer</string>
-    <string name="fingerprint_use_backup">Back-up gebruiken</string>
-    <string name="fingerprint_auth_dialog_title">Authenticatie met vingerafdruk</string>
-    <string name="fingerprint_ok">OK</string>
-    <string name="fingerprint_description">Vingerafdruk bevestigen om verder te gaan</string>
-    <string name="fingerprint_hint">Aanraaksensor</string>
-    <string name="fingerprint_not_recognized">Vingerafdruk niet herkend.Opnieuw proberen.</string>
-    <string name="fingerprint_success">Vingerafdruk herkend</string>
-    <string name="new_fingerprint_enrolled_description">Er werd een nieuwe vingerafdruk aan dit apparaat toegevoegd, waardoor uw wachtwoord is vereist.</string>
-    <string name="secure_lock_screen_required">Beveiligd vergrendelingsscherm vereist!</string>
-</resources>
diff --git a/platforms/android/app/src/main/res/values-pt/fpauth-strings.xml b/platforms/android/app/src/main/res/values-pt/fpauth-strings.xml
deleted file mode 100644 (file)
index 7c3e581..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<resources>
-    <string name="fingerprint_cancel">Cancelar</string>
-    <string name="fingerprint_use_backup">Use o backup</string>
-    <string name="fingerprint_auth_dialog_title">Autenticação de impressão digital</string>
-    <string name="fingerprint_ok">Ok</string>
-    <string name="fingerprint_description">Confirme a impressão digital para continuar</string>
-    <string name="fingerprint_hint">Sensor de toque</string>
-    <string name="fingerprint_not_recognized">impressão digital não reconhecida. Tente novamente.</string>
-    <string name="fingerprint_success">impressão digital reconhecida</string>
-    <string name="new_fingerprint_enrolled_description">Uma nova impressão digital foi adicionada a este dispositivo, é necessário o seu código</string>
-    <string name="secure_lock_screen_required">É necessário um ecrã de bloqueio seguro!</string>
-</resources>
diff --git a/platforms/android/app/src/main/res/values-zh-rTW/fpauth-strings.xml b/platforms/android/app/src/main/res/values-zh-rTW/fpauth-strings.xml
deleted file mode 100644 (file)
index c8345a3..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<resources>
-  <string name="fingerprint_cancel">取消</string>
-  <string name="fingerprint_use_backup">使用手勢密碼</string>
-  <string name="fingerprint_auth_dialog_title">指紋識別</string>
-  <string name="fingerprint_ok">確認</string><string name="fingerprint_description">指紋識別</string>
-  <string name="fingerprint_hint">請觸摸指紋識別傳感器</string>
-  <string name="fingerprint_not_recognized">指紋無法識別,請再試一次</string>
-  <string name="fingerprint_success">指紋識別成功</string>
-  <string name="new_fingerprint_enrolled_description">添加一個新的指紋,需要設置密碼</string>
-  <string name="secure_lock_screen_required">需要安全鎖屏</string>
-</resources>
diff --git a/platforms/android/app/src/main/res/values-zh/fpauth-strings.xml b/platforms/android/app/src/main/res/values-zh/fpauth-strings.xml
deleted file mode 100644 (file)
index 54d38b7..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<resources>
-  <string name="fingerprint_cancel">取消</string>
-  <string name="fingerprint_use_backup">使用手势密码</string>
-  <string name="fingerprint_auth_dialog_title">指纹识别</string>
-  <string name="fingerprint_ok">确认</string><string name="fingerprint_description">指纹识别</string>
-  <string name="fingerprint_hint">请触摸指纹识传感器</string>
-  <string name="fingerprint_not_recognized">指纹无法识别,请再试一次</string>
-  <string name="fingerprint_success">指纹识别成功</string>
-  <string name="new_fingerprint_enrolled_description">添加一个新的指纹,需要设置密码</string>
-  <string name="secure_lock_screen_required">需要安全锁屏</string>
-</resources>
\ No newline at end of file
diff --git a/platforms/android/app/src/main/res/values/biometric-styles.xml b/platforms/android/app/src/main/res/values/biometric-styles.xml
new file mode 100644 (file)
index 0000000..06d9cbb
--- /dev/null
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  Copyright 2019 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+
+<resources>
+    <style name="TransparentTheme" parent="Theme.AppCompat">
+        <item name="android:windowIsTranslucent">true</item>
+        <item name="android:windowBackground">@android:color/transparent</item>
+        <item name="android:windowContentOverlay">@null</item>
+        <item name="android:windowNoTitle">true</item>
+        <item name="android:windowIsFloating">true</item>
+        <item name="android:backgroundDimEnabled">false</item>
+    </style>
+</resources>
\ No newline at end of file
diff --git a/platforms/android/app/src/main/res/values/fpauth-colors.xml b/platforms/android/app/src/main/res/values/fpauth-colors.xml
deleted file mode 100644 (file)
index a24f3c8..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  ~ Copyright (C) 2015 The Android Open Source Project
-  ~
-  ~ Licensed under the Apache License, Version 2.0 (the "License");
-  ~ you may not use this file except in compliance with the License.
-  ~ You may obtain a copy of the License at
-  ~
-  ~      http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~ Unless required by applicable law or agreed to in writing, software
-  ~ distributed under the License is distributed on an "AS IS" BASIS,
-  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  ~ See the License for the specific language governing permissions and
-  ~ limitations under the License
-  -->
-<resources>
-    <color name="warning_color">#f4511e</color>
-    <color name="hint_color">#42000000</color>
-    <color name="success_color">#009688</color>
-</resources>
diff --git a/platforms/android/app/src/main/res/values/fpauth-strings.xml b/platforms/android/app/src/main/res/values/fpauth-strings.xml
deleted file mode 100644 (file)
index 00cc755..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  ~ Copyright (C) 2015 The Android Open Source Project
-  ~
-  ~ Licensed under the Apache License, Version 2.0 (the "License");
-  ~ you may not use this file except in compliance with the License.
-  ~ You may obtain a copy of the License at
-  ~
-  ~      http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~ Unless required by applicable law or agreed to in writing, software
-  ~ distributed under the License is distributed on an "AS IS" BASIS,
-  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  ~ See the License for the specific language governing permissions and
-  ~ limitations under the License
-  -->
-<resources>
-    <string name="fingerprint_cancel">Cancel</string>
-    <string name="fingerprint_use_backup">Use backup</string>
-    <string name="fingerprint_auth_dialog_title">Fingerprint Authentication</string>
-    <string name="fingerprint_ok">Ok</string>
-    <string name="fingerprint_description">Confirm fingerprint to continue</string>
-    <string name="fingerprint_hint">Touch sensor</string>
-    <string name="fingerprint_not_recognized">Fingerprint not recognized. Try again.</string>
-    <string name="fingerprint_success">Fingerprint recognized</string>
-    <string name="new_fingerprint_enrolled_description">A new fingerprint was added to this device, so your password is required.</string>
-    <string name="secure_lock_screen_required">Secure lock screen required!</string>
-</resources>
index da7283d..648e931 100644 (file)
@@ -1,8 +1,5 @@
 <?xml version='1.0' encoding='utf-8'?>
 <widget id="com.dalicitycard.app" version="1.0.6" xmlns="http://www.w3.org/ns/widgets" xmlns:cdv="http://cordova.apache.org/ns/1.0">
-    <feature name="Fingerprint">
-        <param name="android-package" value="de.niklasmerz.cordova.fingerprint.Fingerprint" />
-    </feature>
     <feature name="Whitelist">
         <param name="android-package" value="org.apache.cordova.whitelist.WhitelistPlugin" />
         <param name="onload" value="true" />
@@ -43,6 +40,9 @@
     <feature name="Brightness">
         <param name="android-package" value="org.apache.cordova.plugin.Brightness.BrightnessPlugin" />
     </feature>
+    <feature name="Fingerprint">
+        <param name="android-package" value="de.niklasmerz.cordova.biometric.Fingerprint" />
+    </feature>
     <name short="大理市民卡">dlapp</name>
     <description>
         A sample Apache Cordova application that responds to the deviceready event.
diff --git a/platforms/android/cordova-plugin-fingerprint-aio/app-build.gradle b/platforms/android/cordova-plugin-fingerprint-aio/app-build.gradle
new file mode 100644 (file)
index 0000000..aad4f13
--- /dev/null
@@ -0,0 +1,30 @@
+allprojects {
+    repositories {
+        maven { url 'https://jitpack.io' }
+    }
+}
+
+dependencies {
+
+    /**
+     * The android-biometric.aar file has been taken from com.github.exxbrain:android-biometric library.
+     * Android biometric library is a clone of androidx.biometric library adapted for non-androidx apps.
+     * This project could be found at https://github.com/exxbrain/android-biometric.
+     * It has Apache License 2.0.
+     *
+     * TODO: Temporary solution. Should be removed after moving cordova-android to androidx. Then use androidx.biometric.
+     */
+    implementation 'com.github.exxbrain:android-biometric:0.4'
+
+    implementation 'com.android.support:design:28.0.0'
+    implementation 'com.android.support:appcompat-v7:28.0.0'
+    implementation 'com.android.support:support-v4:28.0.0'
+    implementation 'com.android.support:support-annotations:28.0.0'
+}
+
+android {
+    packagingOptions {
+        exclude 'META-INF/NOTICE'
+        exclude 'META-INF/LICENSE'
+    }
+}
index fb0347b..dbec6c3 100644 (file)
@@ -1,13 +1,5 @@
 cordova.define('cordova/plugin_list', function(require, exports, module) {
   module.exports = [
-    {
-      "id": "cordova-plugin-fingerprint-aio.Fingerprint",
-      "file": "plugins/cordova-plugin-fingerprint-aio/www/Fingerprint.js",
-      "pluginId": "cordova-plugin-fingerprint-aio",
-      "clobbers": [
-        "Fingerprint"
-      ]
-    },
     {
       "id": "cordova-plugin-touch-id.TouchID",
       "file": "plugins/cordova-plugin-touch-id/www/TouchID.js",
@@ -345,41 +337,16 @@ cordova.define('cordova/plugin_list', function(require, exports, module) {
       ]
     },
     {
-      "id": "cordova-plugin-file-opener2.FileOpener2",
-      "file": "plugins/cordova-plugin-file-opener2/www/plugins.FileOpener2.js",
-      "pluginId": "cordova-plugin-file-opener2",
-      "clobbers": [
-        "cordova.plugins.fileOpener2"
-      ]
-    },
-    {
-      "id": "cordova-plugin-file-transfer.FileTransferError",
-      "file": "plugins/cordova-plugin-file-transfer/www/FileTransferError.js",
-      "pluginId": "cordova-plugin-file-transfer",
-      "clobbers": [
-        "window.FileTransferError"
-      ]
-    },
-    {
-      "id": "cordova-plugin-file-transfer.FileTransfer",
-      "file": "plugins/cordova-plugin-file-transfer/www/FileTransfer.js",
-      "pluginId": "cordova-plugin-file-transfer",
-      "clobbers": [
-        "window.FileTransfer"
-      ]
-    },
-    {
-      "id": "cordova-plugin-crop.CropPlugin",
-      "file": "plugins/cordova-plugin-crop/www/crop.js",
-      "pluginId": "cordova-plugin-crop",
+      "id": "cordova-plugin-fingerprint-aio.Fingerprint",
+      "file": "plugins/cordova-plugin-fingerprint-aio/www/Fingerprint.js",
+      "pluginId": "cordova-plugin-fingerprint-aio",
       "clobbers": [
-        "plugins.crop"
+        "Fingerprint"
       ]
     }
   ];
   module.exports.metadata = {
     "cordova-plugin-add-swift-support": "2.0.2",
-    "cordova-plugin-fingerprint-aio": "1.7.0",
     "cordova-plugin-touch-id": "3.3.1",
     "cordova-plugin-whitelist": "1.3.3",
     "cordova-plugin-file": "6.0.1",
@@ -396,8 +363,6 @@ cordova.define('cordova/plugin_list', function(require, exports, module) {
     "cordova-plugin-app-version": "0.1.9",
     "cordova-plugin-wkwebview-engine": "1.2.1",
     "cordova-plugin-brightness": "0.1.5",
-    "cordova-plugin-file-opener2": "2.2.1",
-    "cordova-plugin-file-transfer": "1.7.1",
-    "cordova-plugin-crop": "0.3.1"
+    "cordova-plugin-fingerprint-aio": "3.0.1"
   };
 });
\ No newline at end of file
index 3982139..22ecb6c 100644 (file)
@@ -1,8 +1,28 @@
 cordova.define("cordova-plugin-fingerprint-aio.Fingerprint", function(require, exports, module) {
 /*global cordova */
 
-function Fingerprint() {
-}
+var Fingerprint = function() {
+};
+
+// Plugin Errors
+Fingerprint.prototype.BIOMETRIC_UNKNOWN_ERROR = -100;
+Fingerprint.prototype.BIOMETRIC_UNAVAILABLE = -101;
+Fingerprint.prototype.BIOMETRIC_AUTHENTICATION_FAILED = -102;
+Fingerprint.prototype.BIOMETRIC_SDK_NOT_SUPPORTED = -103;
+Fingerprint.prototype.BIOMETRIC_HARDWARE_NOT_SUPPORTED = -104;
+Fingerprint.prototype.BIOMETRIC_PERMISSION_NOT_GRANTED = -105;
+Fingerprint.prototype.BIOMETRIC_NOT_ENROLLED = -106;
+Fingerprint.prototype.BIOMETRIC_INTERNAL_PLUGIN_ERROR = -107;
+Fingerprint.prototype.BIOMETRIC_DISMISSED = -108;
+Fingerprint.prototype.BIOMETRIC_PIN_OR_PATTERN_DISMISSED = -109;
+Fingerprint.prototype.BIOMETRIC_SCREEN_GUARD_UNSECURED = -110;
+Fingerprint.prototype.BIOMETRIC_LOCKED_OUT = -111;
+Fingerprint.prototype.BIOMETRIC_LOCKED_OUT_PERMANENT = -112;
+
+// Biometric types
+Fingerprint.prototype.BIOMETRIC_TYPE_FINGERPRINT = "finger";
+Fingerprint.prototype.BIOMETRIC_TYPE_FACE = "face";
+Fingerprint.prototype.BIOMETRIC_TYPE_COMMON = "biometric";
 
 Fingerprint.prototype.show = function (params, successCallback, errorCallback) {
   cordova.exec(
index 8a65caa..a2f953f 100644 (file)
@@ -14,3 +14,4 @@ android.library.reference.2=app
 cordova.system.library.1=com.squareup.okhttp3:okhttp-urlconnection:3.10.0
 cordova.gradle.include.1=cordova-plugin-qrscanner/dlapp-qrscanner.gradle
 cordova.system.library.2=com.android.support:support-v4:24.1.1+
+cordova.gradle.include.2=cordova-plugin-fingerprint-aio/app-build.gradle
\ No newline at end of file
index fb5ae44..4b3e322 100644 (file)
@@ -53,9 +53,6 @@
     "cordova-plugin-add-swift-support": {
       "PACKAGE_NAME": "com.supwisdom.dlapp"
     },
-    "cordova-plugin-fingerprint-aio": {
-      "PACKAGE_NAME": "com.supwisdom.dlapp"
-    },
     "cordova-plugin-touch-id": {
       "PACKAGE_NAME": "com.supwisdom.dlapp"
     },
     },
     "cordova-plugin-brightness": {
       "PACKAGE_NAME": "com.dalicitycard.app"
+    },
+    "cordova-plugin-fingerprint-aio": {
+      "PACKAGE_NAME": "com.dalicitycard.app"
     }
   },
   "dependent_plugins": {},
   "modules": [
-    {
-      "file": "plugins/cordova-plugin-fingerprint-aio/www/Fingerprint.js",
-      "id": "cordova-plugin-fingerprint-aio.Fingerprint",
-      "pluginId": "cordova-plugin-fingerprint-aio",
-      "clobbers": [
-        "Fingerprint"
-      ]
-    },
     {
       "file": "plugins/cordova-plugin-touch-id/www/TouchID.js",
       "id": "cordova-plugin-touch-id.TouchID",
       "clobbers": [
         "cordova.plugins.brightness"
       ]
+    },
+    {
+      "file": "plugins/cordova-plugin-fingerprint-aio/www/Fingerprint.js",
+      "id": "cordova-plugin-fingerprint-aio.Fingerprint",
+      "pluginId": "cordova-plugin-fingerprint-aio",
+      "clobbers": [
+        "Fingerprint"
+      ]
     }
   ],
   "plugin_metadata": {
     "cordova-plugin-add-swift-support": "2.0.2",
-    "cordova-plugin-fingerprint-aio": "1.7.0",
     "cordova-plugin-touch-id": "3.3.1",
     "cordova-plugin-whitelist": "1.3.3",
     "cordova-plugin-file": "6.0.1",
     "jpush-phonegap-plugin": "3.7.2",
     "cordova-plugin-app-version": "0.1.9",
     "cordova-plugin-wkwebview-engine": "1.2.1",
-    "cordova-plugin-brightness": "0.1.5"
+    "cordova-plugin-brightness": "0.1.5",
+    "cordova-plugin-fingerprint-aio": "3.0.1"
   }
 }
index 5aef346..41eda28 100644 (file)
@@ -1,13 +1,5 @@
 cordova.define('cordova/plugin_list', function(require, exports, module) {
 module.exports = [
-    {
-        "file": "plugins/cordova-plugin-fingerprint-aio/www/Fingerprint.js",
-        "id": "cordova-plugin-fingerprint-aio.Fingerprint",
-        "pluginId": "cordova-plugin-fingerprint-aio",
-        "clobbers": [
-            "Fingerprint"
-        ]
-    },
     {
         "file": "plugins/cordova-plugin-touch-id/www/TouchID.js",
         "id": "cordova-plugin-touch-id.TouchID",
@@ -369,13 +361,20 @@ module.exports = [
         "clobbers": [
             "cordova.plugins.brightness"
         ]
+    },
+    {
+        "file": "plugins/cordova-plugin-fingerprint-aio/www/Fingerprint.js",
+        "id": "cordova-plugin-fingerprint-aio.Fingerprint",
+        "pluginId": "cordova-plugin-fingerprint-aio",
+        "clobbers": [
+            "Fingerprint"
+        ]
     }
 ];
 module.exports.metadata = 
 // TOP OF METADATA
 {
     "cordova-plugin-add-swift-support": "2.0.2",
-    "cordova-plugin-fingerprint-aio": "1.7.0",
     "cordova-plugin-touch-id": "3.3.1",
     "cordova-plugin-whitelist": "1.3.3",
     "cordova-plugin-file": "6.0.1",
@@ -391,7 +390,8 @@ module.exports.metadata =
     "jpush-phonegap-plugin": "3.7.2",
     "cordova-plugin-app-version": "0.1.9",
     "cordova-plugin-wkwebview-engine": "1.2.1",
-    "cordova-plugin-brightness": "0.1.5"
+    "cordova-plugin-brightness": "0.1.5",
+    "cordova-plugin-fingerprint-aio": "3.0.1"
 }
 // BOTTOM OF METADATA
 });
\ No newline at end of file
index 6c8203d..06dba7a 100644 (file)
@@ -1,7 +1,27 @@
 cordova.define("cordova-plugin-fingerprint-aio.Fingerprint", function(require, exports, module) { /*global cordova */
 
-function Fingerprint() {
-}
+var Fingerprint = function() {
+};
+
+// Plugin Errors
+Fingerprint.prototype.BIOMETRIC_UNKNOWN_ERROR = -100;
+Fingerprint.prototype.BIOMETRIC_UNAVAILABLE = -101;
+Fingerprint.prototype.BIOMETRIC_AUTHENTICATION_FAILED = -102;
+Fingerprint.prototype.BIOMETRIC_SDK_NOT_SUPPORTED = -103;
+Fingerprint.prototype.BIOMETRIC_HARDWARE_NOT_SUPPORTED = -104;
+Fingerprint.prototype.BIOMETRIC_PERMISSION_NOT_GRANTED = -105;
+Fingerprint.prototype.BIOMETRIC_NOT_ENROLLED = -106;
+Fingerprint.prototype.BIOMETRIC_INTERNAL_PLUGIN_ERROR = -107;
+Fingerprint.prototype.BIOMETRIC_DISMISSED = -108;
+Fingerprint.prototype.BIOMETRIC_PIN_OR_PATTERN_DISMISSED = -109;
+Fingerprint.prototype.BIOMETRIC_SCREEN_GUARD_UNSECURED = -110;
+Fingerprint.prototype.BIOMETRIC_LOCKED_OUT = -111;
+Fingerprint.prototype.BIOMETRIC_LOCKED_OUT_PERMANENT = -112;
+
+// Biometric types
+Fingerprint.prototype.BIOMETRIC_TYPE_FINGERPRINT = "finger";
+Fingerprint.prototype.BIOMETRIC_TYPE_FACE = "face";
+Fingerprint.prototype.BIOMETRIC_TYPE_COMMON = "biometric";
 
 Fingerprint.prototype.show = function (params, successCallback, errorCallback) {
   cordova.exec(
index 92c3c27..7e856ef 100644 (file)
@@ -5,7 +5,6 @@
        };
        objectVersion = 46;
        objects = {
-
 /* Begin PBXBuildFile section */
                0207DA581B56EA530066E2B4 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 0207DA571B56EA530066E2B4 /* Images.xcassets */; };
                04347BD0ABAC4EE0B4CDDDB6 /* jcore-ios-2.1.1.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 444DBF371D8346D7BC7EE35D /* jcore-ios-2.1.1.a */; };
@@ -48,7 +47,6 @@
                A42AE846FF7B482FB889AAEB /* QRScanner.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8478FFD487C4004A1CEFCA8 /* QRScanner.swift */; };
                A50EB04ADB24A5CBB680802F /* libPods-dlapp.a in Frameworks */ = {isa = PBXBuildFile; fileRef = D992375F52889311A88544EF /* libPods-dlapp.a */; };
                A54A9FED843144C887EA4286 /* AppDelegate+JPush.m in Sources */ = {isa = PBXBuildFile; fileRef = 91E044FC8377488C886C818B /* AppDelegate+JPush.m */; };
-               B69FF513D1EE4772AFF6050B /* Fingerprint.swift in Sources */ = {isa = PBXBuildFile; fileRef = C2099240B64744E08C91C285 /* Fingerprint.swift */; };
                B8EFB66D03A44372A240B05B /* CDVCamera.m in Sources */ = {isa = PBXBuildFile; fileRef = 80B448E71F8941268B78692C /* CDVCamera.m */; };
                BC39BA77AF0D4F94BC27666A /* CDVDevice.m in Sources */ = {isa = PBXBuildFile; fileRef = A50DE9801E5E4302A78D569C /* CDVDevice.m */; };
                BC998F935D174204820F4015 /* AFURLSessionManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 22AE2683802B4CB1BAF69ABF /* AFURLSessionManager.m */; };
@@ -66,6 +64,7 @@
                F68EA21E51A3463A8FE2EE92 /* CDVWKWebViewUIDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 3B73EA28E46846FF84E6AF02 /* CDVWKWebViewUIDelegate.m */; };
                F939AD8D22BB769B006B371B /* libsqlite3.0.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = F939AD8C22BB769B006B371B /* libsqlite3.0.tbd */; };
                FDE92C386167415E8040F8AB /* AFURLResponseSerialization.m in Sources */ = {isa = PBXBuildFile; fileRef = FDEE8379D7A34C55A616F700 /* AFURLResponseSerialization.m */; };
+               81B8C05354704A02AE1560A0 /* Fingerprint.swift in Sources */ = {isa = PBXBuildFile; fileRef = 39BDB5993A0D495C9E97E995 /* Fingerprint.swift */; };
 /* End PBXBuildFile section */
 
 /* Begin PBXContainerItemProxy section */
                B3CE13EED96B44C0B06B1B2C /* TouchID.m */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 4; includeInIndex = 0; lastKnownFileType = sourcecode.c.objc; name = TouchID.m; path = "cordova-plugin-touch-id/TouchID.m"; sourceTree = "<group>"; };
                B3F9D30FB27A4B26A445BA84 /* CDVExif.h */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 4; includeInIndex = 0; lastKnownFileType = sourcecode.c.h; name = CDVExif.h; path = "cordova-plugin-camera/CDVExif.h"; sourceTree = "<group>"; };
                BA6C5B1A6A6A488790CA41EB /* AFSecurityPolicy.m */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 4; includeInIndex = 0; lastKnownFileType = sourcecode.c.objc; name = AFSecurityPolicy.m; path = "cordova-plugin-advanced-http/AFSecurityPolicy.m"; sourceTree = "<group>"; };
-               C2099240B64744E08C91C285 /* Fingerprint.swift */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 4; includeInIndex = 0; lastKnownFileType = sourcecode.swift; name = Fingerprint.swift; path = "cordova-plugin-fingerprint-aio/Fingerprint.swift"; sourceTree = "<group>"; };
                C44E29C3B190445C98BBAB84 /* CoreFoundation.framework */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = wrapper.framework; name = CoreFoundation.framework; path = System/Library/Frameworks/CoreFoundation.framework; sourceTree = SDKROOT; };
                C8478FFD487C4004A1CEFCA8 /* QRScanner.swift */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 4; includeInIndex = 0; lastKnownFileType = sourcecode.swift; name = QRScanner.swift; path = "cordova-plugin-qrscanner/QRScanner.swift"; sourceTree = "<group>"; };
                CBD6EA74C612474DA862E146 /* libresolv.tbd */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libresolv.tbd; path = usr/lib/libresolv.tbd; sourceTree = SDKROOT; };
                F840E1F0165FE0F500CFE078 /* config.xml */ = {isa = PBXFileReference; lastKnownFileType = text.xml; name = config.xml; path = dlapp/config.xml; sourceTree = "<group>"; };
                F939AD8C22BB769B006B371B /* libsqlite3.0.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libsqlite3.0.tbd; path = usr/lib/libsqlite3.0.tbd; sourceTree = SDKROOT; };
                FC8EA7F3637547AD8BC62127 /* JPushDefine.h */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 4; includeInIndex = 0; lastKnownFileType = sourcecode.c.h; name = JPushDefine.h; path = "jpush-phonegap-plugin/JPushDefine.h"; sourceTree = "<group>"; };
-               FCC7E279D80D4FB9BCF2530A /* Bridging-Header.h */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 4; includeInIndex = 0; lastKnownFileType = sourcecode.c.h; name = "Bridging-Header.h"; path = "cordova-plugin-fingerprint-aio/Bridging-Header.h"; sourceTree = "<group>"; };
                FDEE8379D7A34C55A616F700 /* AFURLResponseSerialization.m */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 4; includeInIndex = 0; lastKnownFileType = sourcecode.c.objc; name = AFURLResponseSerialization.m; path = "cordova-plugin-advanced-http/AFURLResponseSerialization.m"; sourceTree = "<group>"; };
                FE0B455916A4481681D59FE0 /* WebKit.framework */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = wrapper.framework; name = WebKit.framework; path = System/Library/Frameworks/WebKit.framework; sourceTree = SDKROOT; };
+               39BDB5993A0D495C9E97E995 /* Fingerprint.swift */ = {isa = PBXFileReference; name = "Fingerprint.swift"; path = "cordova-plugin-fingerprint-aio/Fingerprint.swift"; sourceTree = "<group>"; fileEncoding = 4; lastKnownFileType = sourcecode.swift; explicitFileType = undefined; includeInIndex = 0; };
+               705239B1B7D9402DA8A9FDA7 /* Bridging-Header.h */ = {isa = PBXFileReference; name = "Bridging-Header.h"; path = "cordova-plugin-fingerprint-aio/Bridging-Header.h"; sourceTree = "<group>"; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; explicitFileType = undefined; includeInIndex = 0; };
 /* End PBXFileReference section */
 
 /* Begin PBXFrameworksBuildPhase section */
                                3BE5364CD5E74AFDAB853364 /* AFURLResponseSerialization.h */,
                                7E931FBE72E74C4887498E5F /* AFURLSessionManager.h */,
                                D4DBE4512BAD4694B7EB5217 /* SDNetworkActivityIndicator.h */,
-                               C2099240B64744E08C91C285 /* Fingerprint.swift */,
-                               FCC7E279D80D4FB9BCF2530A /* Bridging-Header.h */,
                                1ABBE12B040548F8909BFC7B /* CDVStatusBar.m */,
                                8BFF0D502E2241F0A89DF67F /* CDVStatusBar.h */,
                                B3CE13EED96B44C0B06B1B2C /* TouchID.m */,
                                7DC7711D3C76485B9E422E3A /* CDVWKProcessPoolFactory.h */,
                                1E4D2B8A1F474D9883C50B86 /* Brightness.m */,
                                817A61F7D48245FA9567B115 /* Brightness.h */,
+                               39BDB5993A0D495C9E97E995 /* Fingerprint.swift */,
+                               705239B1B7D9402DA8A9FDA7 /* Bridging-Header.h */,
                        );
                        name = Plugins;
                        path = dlapp/Plugins;
                                FDE92C386167415E8040F8AB /* AFURLResponseSerialization.m in Sources */,
                                BC998F935D174204820F4015 /* AFURLSessionManager.m in Sources */,
                                D404D18DD0114DA787E0BB43 /* SDNetworkActivityIndicator.m in Sources */,
-                               B69FF513D1EE4772AFF6050B /* Fingerprint.swift in Sources */,
                                CAE5A91F948A472F9D872EC8 /* CDVStatusBar.m in Sources */,
                                D834895F80744E0F96D59047 /* TouchID.m in Sources */,
                                C61263FC7FE642E9B25A81E5 /* DisableStatusbar.m in Sources */,
                                F68EA21E51A3463A8FE2EE92 /* CDVWKWebViewUIDelegate.m in Sources */,
                                1F969D21D7EF4CF1A547A1DF /* CDVWKProcessPoolFactory.m in Sources */,
                                C0A6FD40F47B434496535606 /* Brightness.m in Sources */,
+                               81B8C05354704A02AE1560A0 /* Fingerprint.swift in Sources */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
index 93f7d4b..1711166 100644 (file)
Binary files a/platforms/ios/dlapp/Images.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png and b/platforms/ios/dlapp/Images.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png differ
index 338c489..8003676 100644 (file)
Binary files a/platforms/ios/dlapp/Images.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png and b/platforms/ios/dlapp/Images.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png differ
index 26304e4..2961408 100644 (file)
Binary files a/platforms/ios/dlapp/Images.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png and b/platforms/ios/dlapp/Images.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png differ
index 3179c09..458cfdc 100644 (file)
Binary files a/platforms/ios/dlapp/Images.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png and b/platforms/ios/dlapp/Images.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png differ
index 6807263..2efdc6a 100644 (file)
Binary files a/platforms/ios/dlapp/Images.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png and b/platforms/ios/dlapp/Images.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png differ
index 3f765b9..53a7b33 100644 (file)
Binary files a/platforms/ios/dlapp/Images.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png and b/platforms/ios/dlapp/Images.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png differ
index 338c489..8003676 100644 (file)
Binary files a/platforms/ios/dlapp/Images.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png and b/platforms/ios/dlapp/Images.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png differ
index 5159c6d..63f3b12 100644 (file)
Binary files a/platforms/ios/dlapp/Images.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png and b/platforms/ios/dlapp/Images.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png differ
index a5394ab..97b8089 100644 (file)
Binary files a/platforms/ios/dlapp/Images.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png and b/platforms/ios/dlapp/Images.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png differ
index a5394ab..97b8089 100644 (file)
Binary files a/platforms/ios/dlapp/Images.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png and b/platforms/ios/dlapp/Images.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png differ
index 28db6a7..c47ba12 100644 (file)
Binary files a/platforms/ios/dlapp/Images.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png and b/platforms/ios/dlapp/Images.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png differ
index ee96b32..8ede09f 100644 (file)
Binary files a/platforms/ios/dlapp/Images.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png and b/platforms/ios/dlapp/Images.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png differ
index f4e7346..923ccab 100644 (file)
Binary files a/platforms/ios/dlapp/Images.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png and b/platforms/ios/dlapp/Images.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png differ
index 86c995d..cfb60e6 100644 (file)
Binary files a/platforms/ios/dlapp/Images.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png and b/platforms/ios/dlapp/Images.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png differ
index eb0ca49..38db89b 100644 (file)
Binary files a/platforms/ios/dlapp/Images.xcassets/AppIcon.appiconset/ItunesArtwork@2x.png and b/platforms/ios/dlapp/Images.xcassets/AppIcon.appiconset/ItunesArtwork@2x.png differ
index cfd1080..34df640 100644 (file)
Binary files a/platforms/ios/dlapp/Images.xcassets/iTunesArtwork@1x.png and b/platforms/ios/dlapp/Images.xcassets/iTunesArtwork@1x.png differ
index eb0ca49..38db89b 100644 (file)
Binary files a/platforms/ios/dlapp/Images.xcassets/iTunesArtwork@2x.png and b/platforms/ios/dlapp/Images.xcassets/iTunesArtwork@2x.png differ
index d6e68b2..317adb1 100644 (file)
Binary files a/platforms/ios/dlapp/Images.xcassets/iTunesArtwork@3x.png and b/platforms/ios/dlapp/Images.xcassets/iTunesArtwork@3x.png differ
index 547aeb2..1f01be4 100644 (file)
@@ -1,23 +1,47 @@
 import Foundation
 import LocalAuthentication
 
+
 @objc(Fingerprint) class Fingerprint : CDVPlugin {
 
+    enum PluginError:Int {
+        case BIOMETRIC_UNKNOWN_ERROR = -100
+        case BIOMETRIC_UNAVAILABLE = -101
+        case BIOMETRIC_AUTHENTICATION_FAILED = -102
+        case BIOMETRIC_PERMISSION_NOT_GRANTED = -105
+        case BIOMETRIC_NOT_ENROLLED = -106
+        case BIOMETRIC_DISMISSED = -108
+        case BIOMETRIC_SCREEN_GUARD_UNSECURED = -110
+        case BIOMETRIC_LOCKED_OUT = -111
+    }
+
+    struct ErrorCodes {
+        var code: Int
+    }
+
+
     @objc(isAvailable:)
     func isAvailable(_ command: CDVInvokedUrlCommand){
         let authenticationContext = LAContext();
         var biometryType = "finger";
+        var errorResponse: [AnyHashable: Any] = [
+            "code": 0,
+            "message": "Not Available"
+        ];
         var error:NSError?;
         let policy:LAPolicy = .deviceOwnerAuthenticationWithBiometrics;
-
+        var pluginResult = CDVPluginResult(status: CDVCommandStatus_ERROR, messageAs: "Not available");
         let available = authenticationContext.canEvaluatePolicy(policy, error: &error);
 
+        var results: [String : Any]
+
         if(error != nil){
             biometryType = "none";
+            errorResponse["code"] = error?.code;
+            errorResponse["message"] = error?.localizedDescription;
         }
 
-        var pluginResult = CDVPluginResult(status: CDVCommandStatus_ERROR, messageAs: "Not available");
-        if available == true {
+        if (available == true) {
             if #available(iOS 11.0, *) {
                 switch(authenticationContext.biometryType) {
                 case .none:
@@ -30,6 +54,22 @@ import LocalAuthentication
             }
 
             pluginResult = CDVPluginResult(status: CDVCommandStatus_OK, messageAs: biometryType);
+        }else{
+            var code: Int;
+            switch(error!._code) {
+                case Int(kLAErrorBiometryNotAvailable):
+                    code = PluginError.BIOMETRIC_UNAVAILABLE.rawValue;
+                    break;
+                case Int(kLAErrorBiometryNotEnrolled):
+                    code = PluginError.BIOMETRIC_NOT_ENROLLED.rawValue;
+                    break;
+
+                default:
+                    code = PluginError.BIOMETRIC_UNKNOWN_ERROR.rawValue;
+                    break;
+            }
+            results = ["code": code, "message": error!.localizedDescription];
+            pluginResult = CDVPluginResult(status: CDVCommandStatus_ERROR, messageAs: results);
         }
 
         commandDelegate.send(pluginResult, callbackId:command.callbackId);
@@ -39,7 +79,10 @@ import LocalAuthentication
     @objc(authenticate:)
     func authenticate(_ command: CDVInvokedUrlCommand){
         let authenticationContext = LAContext();
-        var pluginResult = CDVPluginResult(status: CDVCommandStatus_ERROR, messageAs: "Something went wrong");
+        var errorResponse: [AnyHashable: Any] = [
+            "message": "Something went wrong"
+        ];
+        var pluginResult = CDVPluginResult(status: CDVCommandStatus_ERROR, messageAs: errorResponse);
         var reason = "Authentication";
         var policy:LAPolicy = .deviceOwnerAuthentication;
         let data  = command.arguments[0] as AnyObject?;
@@ -49,17 +92,17 @@ import LocalAuthentication
                 authenticationContext.localizedFallbackTitle = "";
                 policy = .deviceOwnerAuthenticationWithBiometrics;
             } else {
-                if let localizedFallbackTitle = data?["localizedFallbackTitle"] as! String? {
-                    authenticationContext.localizedFallbackTitle = localizedFallbackTitle;
+                if let fallbackButtonTitle = data?["fallbackButtonTitle"] as! String? {
+                    authenticationContext.localizedFallbackTitle = fallbackButtonTitle;
+                }else{
+                    authenticationContext.localizedFallbackTitle = "Use Pin";
                 }
             }
         }
 
         // Localized reason
-        if let localizedReason = data?["localizedReason"] as! String? {
-            reason = localizedReason;
-        }else if let clientId = data?["clientId"] as! String? {
-            reason = clientId;
+        if let description = data?["description"] as! String? {
+            reason = description;
         }
 
         authenticationContext.evaluatePolicy(
@@ -69,17 +112,32 @@ import LocalAuthentication
                 if( success ) {
                     pluginResult = CDVPluginResult(status: CDVCommandStatus_OK, messageAs: "Success");
                 }else {
-                    // Check if there is an error
-                    if error != nil {
-                        pluginResult = CDVPluginResult(status: CDVCommandStatus_ERROR, messageAs: "Error: \(String(describing: error?.localizedDescription))")
+                    if (error != nil) {
+
+                        var errorCodes = [Int: ErrorCodes]()
+                        var errorResult: [String : Any] = ["code":  PluginError.BIOMETRIC_UNKNOWN_ERROR.rawValue, "message": error?.localizedDescription ?? ""];
+
+                        errorCodes[1] = ErrorCodes(code: PluginError.BIOMETRIC_AUTHENTICATION_FAILED.rawValue)
+                        errorCodes[2] = ErrorCodes(code: PluginError.BIOMETRIC_DISMISSED.rawValue)
+                        errorCodes[5] = ErrorCodes(code: PluginError.BIOMETRIC_SCREEN_GUARD_UNSECURED.rawValue)
+                        errorCodes[6] = ErrorCodes(code: PluginError.BIOMETRIC_UNAVAILABLE.rawValue)
+                        errorCodes[7] = ErrorCodes(code: PluginError.BIOMETRIC_NOT_ENROLLED.rawValue)
+                        errorCodes[8] = ErrorCodes(code: PluginError.BIOMETRIC_LOCKED_OUT.rawValue)
+
+                        let errorCode = abs(error!._code)
+                        if let e = errorCodes[errorCode] {
+                           errorResult = ["code": e.code, "message": error!.localizedDescription];
+                        }
+
+                        pluginResult = CDVPluginResult(status: CDVCommandStatus_ERROR, messageAs: errorResult);
                     }
                 }
                 self.commandDelegate.send(pluginResult, callbackId:command.callbackId);
-        });
+            }
+        );
     }
 
     override func pluginInitialize() {
         super.pluginInitialize()
     }
-}
-
+}
\ No newline at end of file
index 3ae113a..b06fe28 100755 (executable)
@@ -26,9 +26,6 @@
     <feature name="CordovaHttpPlugin">
         <param name="ios-package" value="CordovaHttpPlugin" />
     </feature>
-    <feature name="Fingerprint">
-        <param name="ios-package" value="Fingerprint" />
-    </feature>
     <feature name="StatusBar">
         <param name="ios-package" value="CDVStatusBar" />
         <param name="onload" value="true" />
@@ -67,6 +64,9 @@
     <feature name="Brightness">
         <param name="ios-package" value="Brightness" />
     </feature>
+    <feature name="Fingerprint">
+        <param name="ios-package" value="Fingerprint" />
+    </feature>
     <name short="大理市民卡">dlapp</name>
     <description>
         A sample Apache Cordova application that responds to the deviceready event.
index 7b9d86f..8247df1 100644 (file)
               "xml": "<feature name=\"CordovaHttpPlugin\"><param name=\"ios-package\" value=\"CordovaHttpPlugin\" /></feature>",
               "count": 1
             },
-            {
-              "xml": "<feature name=\"Fingerprint\"><param name=\"ios-package\" value=\"Fingerprint\" /></feature>",
-              "count": 1
-            },
             {
               "xml": "<feature name=\"StatusBar\"><param name=\"ios-package\" value=\"CDVStatusBar\" /><param name=\"onload\" value=\"true\" /></feature>",
               "count": 1
             {
               "xml": "<feature name=\"Brightness\"><param name=\"ios-package\" value=\"Brightness\" /></feature>",
               "count": 1
+            },
+            {
+              "xml": "<feature name=\"Fingerprint\"><param name=\"ios-package\" value=\"Fingerprint\" /></feature>",
+              "count": 1
             }
           ]
         }
       "*-Info.plist": {
         "parents": {
           "NSFaceIDUsageDescription": [
-            {
-              "xml": "<string>认证中...</string>",
-              "count": 1
-            },
             {
               "xml": "<string> </string>",
-              "count": 1
+              "count": 2
             }
           ],
           "NSCameraUsageDescription": [
     "cordova-plugin-advanced-http": {
       "PACKAGE_NAME": "$(PRODUCT_BUNDLE_IDENTIFIER)"
     },
-    "cordova-plugin-fingerprint-aio": {
-      "FACEID_USAGE_DESCRIPTION": "认证中...",
-      "PACKAGE_NAME": "$(PRODUCT_BUNDLE_IDENTIFIER)"
-    },
     "cordova-plugin-statusbar": {
       "PACKAGE_NAME": "$(PRODUCT_BUNDLE_IDENTIFIER)"
     },
     },
     "cordova-plugin-brightness": {
       "PACKAGE_NAME": "$(PRODUCT_BUNDLE_IDENTIFIER)"
+    },
+    "cordova-plugin-fingerprint-aio": {
+      "FACEID_USAGE_DESCRIPTION": " ",
+      "PACKAGE_NAME": "$(PRODUCT_BUNDLE_IDENTIFIER)"
     }
   },
   "dependent_plugins": {},
         "cordova.plugin.http"
       ]
     },
-    {
-      "id": "cordova-plugin-fingerprint-aio.Fingerprint",
-      "file": "plugins/cordova-plugin-fingerprint-aio/www/Fingerprint.js",
-      "pluginId": "cordova-plugin-fingerprint-aio",
-      "clobbers": [
-        "Fingerprint"
-      ]
-    },
     {
       "id": "cordova-plugin-statusbar.statusbar",
       "file": "plugins/cordova-plugin-statusbar/www/statusbar.js",
       "clobbers": [
         "cordova.plugins.brightness"
       ]
+    },
+    {
+      "id": "cordova-plugin-fingerprint-aio.Fingerprint",
+      "file": "plugins/cordova-plugin-fingerprint-aio/www/Fingerprint.js",
+      "pluginId": "cordova-plugin-fingerprint-aio",
+      "clobbers": [
+        "Fingerprint"
+      ]
     }
   ],
   "plugin_metadata": {
     "cordova-plugin-add-swift-support": "2.0.2",
     "cordova-plugin-file": "6.0.1",
     "cordova-plugin-advanced-http": "2.1.1",
-    "cordova-plugin-fingerprint-aio": "1.7.0",
     "cordova-plugin-statusbar": "2.4.2",
     "cordova-plugin-touch-id": "3.3.1",
     "cordova-plugin-whitelist": "1.3.3",
     "jpush-phonegap-plugin": "3.7.2",
     "cordova-plugin-app-version": "0.1.9",
     "cordova-plugin-wkwebview-engine": "1.2.1",
-    "cordova-plugin-brightness": "0.1.5"
+    "cordova-plugin-brightness": "0.1.5",
+    "cordova-plugin-fingerprint-aio": "3.0.1"
   }
 }
index eca1f34..ed613ac 100644 (file)
@@ -231,14 +231,6 @@ cordova.define('cordova/plugin_list', function(require, exports, module) {
         "cordova.plugin.http"
       ]
     },
-    {
-      "id": "cordova-plugin-fingerprint-aio.Fingerprint",
-      "file": "plugins/cordova-plugin-fingerprint-aio/www/Fingerprint.js",
-      "pluginId": "cordova-plugin-fingerprint-aio",
-      "clobbers": [
-        "Fingerprint"
-      ]
-    },
     {
       "id": "cordova-plugin-statusbar.statusbar",
       "file": "plugins/cordova-plugin-statusbar/www/statusbar.js",
@@ -359,13 +351,20 @@ cordova.define('cordova/plugin_list', function(require, exports, module) {
       "clobbers": [
         "cordova.plugins.brightness"
       ]
+    },
+    {
+      "id": "cordova-plugin-fingerprint-aio.Fingerprint",
+      "file": "plugins/cordova-plugin-fingerprint-aio/www/Fingerprint.js",
+      "pluginId": "cordova-plugin-fingerprint-aio",
+      "clobbers": [
+        "Fingerprint"
+      ]
     }
   ];
   module.exports.metadata = {
     "cordova-plugin-add-swift-support": "2.0.2",
     "cordova-plugin-file": "6.0.1",
     "cordova-plugin-advanced-http": "2.1.1",
-    "cordova-plugin-fingerprint-aio": "1.7.0",
     "cordova-plugin-statusbar": "2.4.2",
     "cordova-plugin-touch-id": "3.3.1",
     "cordova-plugin-whitelist": "1.3.3",
@@ -379,6 +378,7 @@ cordova.define('cordova/plugin_list', function(require, exports, module) {
     "jpush-phonegap-plugin": "3.7.2",
     "cordova-plugin-app-version": "0.1.9",
     "cordova-plugin-wkwebview-engine": "1.2.1",
-    "cordova-plugin-brightness": "0.1.5"
+    "cordova-plugin-brightness": "0.1.5",
+    "cordova-plugin-fingerprint-aio": "3.0.1"
   };
 });
\ No newline at end of file
index 3982139..22ecb6c 100644 (file)
@@ -1,8 +1,28 @@
 cordova.define("cordova-plugin-fingerprint-aio.Fingerprint", function(require, exports, module) {
 /*global cordova */
 
-function Fingerprint() {
-}
+var Fingerprint = function() {
+};
+
+// Plugin Errors
+Fingerprint.prototype.BIOMETRIC_UNKNOWN_ERROR = -100;
+Fingerprint.prototype.BIOMETRIC_UNAVAILABLE = -101;
+Fingerprint.prototype.BIOMETRIC_AUTHENTICATION_FAILED = -102;
+Fingerprint.prototype.BIOMETRIC_SDK_NOT_SUPPORTED = -103;
+Fingerprint.prototype.BIOMETRIC_HARDWARE_NOT_SUPPORTED = -104;
+Fingerprint.prototype.BIOMETRIC_PERMISSION_NOT_GRANTED = -105;
+Fingerprint.prototype.BIOMETRIC_NOT_ENROLLED = -106;
+Fingerprint.prototype.BIOMETRIC_INTERNAL_PLUGIN_ERROR = -107;
+Fingerprint.prototype.BIOMETRIC_DISMISSED = -108;
+Fingerprint.prototype.BIOMETRIC_PIN_OR_PATTERN_DISMISSED = -109;
+Fingerprint.prototype.BIOMETRIC_SCREEN_GUARD_UNSECURED = -110;
+Fingerprint.prototype.BIOMETRIC_LOCKED_OUT = -111;
+Fingerprint.prototype.BIOMETRIC_LOCKED_OUT_PERMANENT = -112;
+
+// Biometric types
+Fingerprint.prototype.BIOMETRIC_TYPE_FINGERPRINT = "finger";
+Fingerprint.prototype.BIOMETRIC_TYPE_FACE = "face";
+Fingerprint.prototype.BIOMETRIC_TYPE_COMMON = "biometric";
 
 Fingerprint.prototype.show = function (params, successCallback, errorCallback) {
   cordova.exec(
index c516159..638fa31 100644 (file)
@@ -7,9 +7,6 @@
     "files": {}
   },
   "installed_plugins": {
-    "cordova-plugin-fingerprint-aio": {
-      "PACKAGE_NAME": "com.supwisdom.dlapp"
-    },
     "cordova-plugin-touch-id": {
       "PACKAGE_NAME": "com.supwisdom.dlapp"
     },
@@ -57,6 +54,9 @@
     },
     "cordova-plugin-file": {
       "PACKAGE_NAME": "com.supwisdom.dlapp"
+    },
+    "cordova-plugin-fingerprint-aio": {
+      "PACKAGE_NAME": "com.dalicitycard.app"
     }
   },
   "dependent_plugins": {
index fc76262..34b89f7 100644 (file)
@@ -7,9 +7,6 @@
     "files": {}
   },
   "installed_plugins": {
-    "cordova-plugin-fingerprint-aio": {
-      "PACKAGE_NAME": "com.supwisdom.dlapp"
-    },
     "cordova-plugin-touch-id": {
       "PACKAGE_NAME": "com.supwisdom.dlapp"
     },
@@ -56,6 +53,9 @@
     },
     "cordova-plugin-file": {
       "PACKAGE_NAME": "com.supwisdom.dlapp"
+    },
+    "cordova-plugin-fingerprint-aio": {
+      "PACKAGE_NAME": "com.dalicitycard.app"
     }
   },
   "dependent_plugins": {
index a4628bf..3593189 100644 (file)
+# This Travis configuration file is built after a Cordova Paramedic 
+# specific template with minimal modifications and adaptations:
+# https://github.com/apache/cordova-paramedic/blob/master/.travis.yml
+
 sudo: false
 addons:
   jwt:
     secure: f0G7Z/0N1ACi5pFg32P4kr8tVd5EOADDne5a8/MtabGTjeH0/QZl+4xKIgemXle6BJn949Gqpx4+XkmaKmDHHfIsV+9GmLwqGpGSyQMMoeBI0Lfxzh8aecYDxfJKBYmdmpJcyG3yKa42nxQFEMIljf0NJEmNN8AAglsaSh5VQq2dlv1aXaoJz18dpgRVE1cJ4rvUJN+fOrZYjRsqw9ev+11J7cwRONsBB/Yx+56tsverD2uC4Xutj58CEaw7WRk4BLMqehkGO0/ez2Ofc9dBDfc4ZHqHxZMfqjYO5r95VFclyIgto9ToW2kazuK+NZMgaX5wEBp+ktVQGHQw+rRunANplJt14AXpu7Elpfp04Hb4qjBQTYCXellNJ1TgLJLhP6a3P4nTUBrZ9I5mjSGI8ckvUEb1066KyGJmMIPs64z6BJgDHd91PP+cDq6MqUm+n+m24l6Ou/iLDmxaEs6peEctx5A6hACnNwyyB5MEeqZVbksFkNoYw9pxbTj1bBtBbg5QRHC7+Bd8mrN12VOi2wA2N8dFgO3Np+sfZriq/CXfCPrDNYPX8IwF9HEkm2J+PLW1MD8Kx2XwALCqKjU6md0hKui5LdhNWlpAiNK/eBLtJEF2egaMkQw1JPQYxHIyAAi4yUSYYVd64hb9rgUSTNiywRddmKovBChiwiTsmFc=
 env:
   global:
-  - SAUCE_USERNAME=NiklasMerz
-  - TRAVIS_NODE_VERSION="lts/*"
+    - SAUCE_USERNAME=NiklasMerz
+    - TRAVIS_NODE_VERSION=8
+    - ANDROID_API_LEVEL=28
+    - ANDROID_BUILD_TOOLS_VERSION=28.0.3
+
+language: node_js
+node_js: 8
+
+# yaml anchor/alias: https://medium.com/@tommyvn/travis-yml-dry-with-anchors-8b6a3ac1b027
+
+_ios: &_ios
+  os: osx
+  osx_image: xcode10.2
+
+_android: &_android
+  language: android
+  os: linux
+  jdk: oraclejdk8
+  android:
+    components:
+      - tools
+      - build-tools-$ANDROID_BUILD_TOOLS_VERSION
+      - android-$ANDROID_API_LEVEL
+    licenses:
+      - 'android-sdk-preview-license-.+'
+      - 'android-sdk-license-.+'
+      - 'google-gdk-license-.+'
+
 matrix:
   include:
-  - env: PLATFORM=android-7.0
-    os: linux
-    language: android
-    jdk: oraclejdk8
-    android:
-      components:
-      - tools
-      - build-tools-26.0.2
-  - env: PLATFORM=ios-10.0
-    os: osx
-    osx_image: xcode9.2
-    language: node_js
-    node_js: 'lts/*'
+    # local tests, without saucelabs
+    - env: PLATFORM=local/ios-10.0
+      <<: *_ios
+
+    # many tests with saucelabs
+
+    - env: PLATFORM=ios-11.3
+      <<: *_ios
+    - env: PLATFORM=ios-12.0
+      <<: *_ios
+
+    - env: PLATFORM=android-8.1
+      <<: *_android
+    - env: PLATFORM=android-9.0
+      <<: *_android
+
 before_install:
-- rm -rf ~/.nvm && git clone https://github.com/creationix/nvm.git ~/.nvm && (cd ~/.nvm
-  && git checkout `git describe --abbrev=0 --tags`) && source ~/.nvm/nvm.sh && nvm
-  install $TRAVIS_NODE_VERSION
-- node --version
-- if [[ "$PLATFORM" =~ android ]]; then gradle --version; fi
-- if [[ "$PLATFORM" =~ ios ]]; then npm install -g ios-deploy; fi
-- if [[ "$PLATFORM" =~ android ]]; then echo y | android update sdk -u --filter android-25,android-26;
-  fi
-- git clone https://github.com/apache/cordova-paramedic /tmp/paramedic && pushd /tmp/paramedic
-  && npm install && popd
-- npm install -g cordova@7.0.1
+  # manually install Node for `language: android`
+  - if [[ "$PLATFORM" =~ android ]]; then nvm install $TRAVIS_NODE_VERSION; fi 
+  - node --version
+  - if [[ "$PLATFORM" =~ android ]]; then gradle --version; fi
+  - if [[ "$PLATFORM" =~ ios ]]; then npm install -g ios-deploy; fi
+  - npm install -g cordova
+  # install paramedic if not running on paramedic repo
+  - if ! [[ "$TRAVIS_REPO_SLUG" =~ cordova-paramedic ]]; then npm install -g github:apache/cordova-paramedic; fi 
+
 install:
-- npm install
+  - npm install
+
+before_script:
+  - |
+    if [[ "$TRAVIS_REPO_SLUG" =~ cordova-paramedic ]]; then 
+      # when used in the cordova-paramedic repo
+      TEST_COMMAND="npm run eslint"
+      PARAMEDIC_PLUGIN_TO_TEST="./spec/testable-plugin/"
+      PARAMEDIC_COMMAND="node main.js"
+    else 
+      # when used in any other (plugin) repo
+      TEST_COMMAND="npm test"
+      PARAMEDIC_PLUGIN_TO_TEST=$(pwd)
+      PARAMEDIC_COMMAND="cordova-paramedic"
+    fi
+  - PARAMEDIC_BUILDNAME=travis-$TRAVIS_REPO_SLUG-$TRAVIS_JOB_NUMBER
+  - |
+    echo "Variables now are set to:"
+    echo "TEST_COMMAND=$TEST_COMMAND"
+    echo "ADDITIONAL_TESTS=$ADDITIONAL_TESTS"
+    echo "PARAMEDIC_COMMAND=$PARAMEDIC_COMMAND"
+    echo "PLATFORM=$PLATFORM"
+    echo "PARAMEDIC_PLUGIN_TO_TEST=$PARAMEDIC_PLUGIN_TO_TEST"
+    echo "PARAMEDIC_BUILDNAME=$PARAMEDIC_BUILDNAME"
 script:
-- node /tmp/paramedic/main.js --config pr/$PLATFORM --plugin $(pwd) --shouldUseSauce
-  --buildName travis-plugin-fingerprint-aio-$TRAVIS_JOB_NUMBER
+  - $TEST_COMMAND
+  - if [[ "$ADDITIONAL_TESTS_DIR" != "" ]]; then
+      cd $ADDITIONAL_TESTS_DIR && npm install && npm test;
+    else 
+      $PARAMEDIC_COMMAND --config ./pr/$PLATFORM --plugin $PARAMEDIC_PLUGIN_TO_TEST --buildName $PARAMEDIC_BUILDNAME; 
+    fi
 notifications:
   email: false
   slack:
index 7e3fa3d..bb16d1f 100644 (file)
 
 * Android - Minimum SDK 23
 * iOS - **XCode 9.2 or higher** required
-  * _Please set `<preference name="UseSwiftLanguageVersion" value="3.2" />` in your config.xml_
+  * _Please set `<preference name="UseSwiftLanguageVersion" value="4.0" />` in your config.xml_
 
 
 ## How to use
 
----
-
 **[Tutorial about using this plugin with Ionic](https://www.youtube.com/watch?v=tQDChMJ6er8)** thanks to Paul Halliday
 
 [Examples](https://github.com/NiklasMerz/fingerprint-aio-demo)
@@ -84,33 +82,59 @@ Fingerprint.isAvailable(isAvailableSuccess, isAvailableError);
       alert("Fingerprint available");
     }
 
-    function isAvailableError(message) {
-      alert(message);
+    function isAvailableError(error) {
+      // 'error' will be an object with an error code and message
+      alert(error.message);
     }
 ```
 
 ### Show authentication dialogue
 ```javascript
 Fingerprint.show({
-      clientId: "Fingerprint-Demo",
-      clientSecret: "password" //Only necessary for Android
+      description: "Some biometric description"
     }, successCallback, errorCallback);
 
     function successCallback(){
-      alert("Authentication successfull");
+      alert("Authentication successful");
     }
 
-    function errorCallback(err){
-      alert("Authentication invalid " + err);
+    function errorCallback(error){
+      alert("Authentication invalid " + error.message);
     }
 ```
-**Optional parameters**
-
-* __disableBackup__: If `true` remove backup option on authentication dialogue for Android. Default: `false`.
-* __localizedFallbackTitle__ (iOS only): Title of fallback button.
-* __localizedReason__ (iOS only): Description in authentication dialogue.
-
-## Thanks to the authors of the original fingerprint plugins
+### Optional parameters
+
+* __title__: Title in authentication dialogue. Default: `"<APP_NAME> Biometric Sign On"`
+* __subtitle__: Subtitle in authentication dialogue. Default: `null`
+* __description__: Description in authentication dialogue. Defaults:
+  * iOS: `"Authenticate"` (iOS' [evaluatePolicy()](https://developer.apple.com/documentation/localauthentication/lacontext/1514176-evaluatepolicy?language=objc) requires this field)
+  * Android: `null`
+* __fallbackButtonTitle__: Title of fallback button. Defaults:
+  * When **disableBackup** is true
+     *  `"Cancel"`
+  * When **disableBackup** is false
+     * iOS: `"Use PIN"`
+     * Android: `"Use Backup"` (Because backup could be anything pin/pattern/password ..haven't figured out a reliable way to determine lock type yet [source](https://stackoverflow.com/questions/7768879/check-whether-lock-was-enabled-or-not/18720287))
+* __disableBackup__: If `true` remove backup option on authentication dialogue. Default: `false`. This is useful if you want to implement your own fallback.
+* __cancelButtonTitle__: For cancel button on Android
+
+### Constants
+- **BIOMETRIC_UNKNOWN_ERROR** = `-100`;
+- **BIOMETRIC_UNAVAILABLE** = `-101`;
+- **BIOMETRIC_AUTHENTICATION_FAILED** = `-102`;
+- **BIOMETRIC_SDK_NOT_SUPPORTED** = `-103`;
+- **BIOMETRIC_HARDWARE_NOT_SUPPORTED** = `-104`;
+- **BIOMETRIC_PERMISSION_NOT_GRANTED** = `-105`;
+- **BIOMETRIC_NOT_ENROLLED** = `-106`;
+- **BIOMETRIC_INTERNAL_PLUGIN_ERROR** = `-107`;
+- **BIOMETRIC_DISMISSED** = `-108`;
+- **BIOMETRIC_PIN_OR_PATTERN_DISMISSED** = `-109`;
+- **BIOMETRIC_SCREEN_GUARD_UNSECURED** = `-110`;
+- **BIOMETRIC_LOCKED_OUT** = `-111`;
+- **BIOMETRIC_LOCKED_OUT_PERMANENT** = `-112`;
+***
+
+Thanks to the authors of the original fingerprint plugins
 
 Some code is refactored from their projects and I learned how to make Cordova plugins from their great plugins:
 
@@ -120,7 +144,9 @@ Some code is refactored from their projects and I learned how to make Cordova pl
 
 [iOS](https://github.com/EddyVerbruggen/cordova-plugin-touch-id)
 
+Starting with version 3.0.0 the iOS and Android parts are written from scratch.
+
 ## License
 
-* Project and iOS source: [MIT](https://opensource.org/licenses/MIT)
-* Android source: [MIT](https://opensource.org/licenses/MIT) and [Apache 2.0](https://www.apache.org/licenses/LICENSE-2.0)
+The project is MIT licensed: [MIT](https://opensource.org/licenses/MIT).
+
index a79ee09..5ad47d9 100644 (file)
@@ -1,8 +1,8 @@
 {
   "_from": "cordova-plugin-fingerprint-aio",
-  "_id": "cordova-plugin-fingerprint-aio@1.7.0",
+  "_id": "cordova-plugin-fingerprint-aio@3.0.1",
   "_inBundle": false,
-  "_integrity": "sha512-pV+JUeEhZUP85nXs9KMpHRClZppVHnpZA5h+8ReKBi4AV4vnzAcpUDBgFN7g3Ra83zmREYI/MqrlZlXn16pg3g==",
+  "_integrity": "sha512-Sgbv8Ykk74Ov1foEZg77owIqmHZoGktsv41rmW8KAAMf2JE93AawvQdUCYYROnk+ozG3D9ItELa5yhYU8i7Zhw==",
   "_location": "/cordova-plugin-fingerprint-aio",
   "_phantomChildren": {},
   "_requested": {
@@ -19,8 +19,8 @@
     "#USER",
     "/"
   ],
-  "_resolved": "https://registry.npmjs.org/cordova-plugin-fingerprint-aio/-/cordova-plugin-fingerprint-aio-1.7.0.tgz",
-  "_shasum": "7f998587106aa47df3cb9666396b9021b6b419f7",
+  "_resolved": "https://registry.npmjs.org/cordova-plugin-fingerprint-aio/-/cordova-plugin-fingerprint-aio-3.0.1.tgz",
+  "_shasum": "030a732773e7690d74a1aadbab66c8a8b294ea42",
   "_spec": "cordova-plugin-fingerprint-aio",
   "_where": "/Users/shuwei/works2/cordova/dlapp",
   "author": {
   "devDependencies": {
     "cordova-paramedic": "git+https://github.com/apache/cordova-paramedic.git",
     "cordova-plugin-xml": "^0.1.2",
-    "eslint": "^5.7.0",
+    "eslint": "^6.5.1",
     "jasmine": "^3.2.0"
   },
+  "engines": {
+    "cordovaDependencies": {
+      ">=3.0.0": {
+        "cordova-android": ">=8.0.0"
+      }
+    }
+  },
   "homepage": "https://github.com/niklasmerz/cordova-plugin-fingerprint-aio#readme",
   "keywords": [
     "cordova",
     "url": "git+https://github.com/niklasmerz/cordova-plugin-fingerprint-aio.git"
   },
   "scripts": {
+    "eslint": "npx eslint www",
     "plugin-version": "cordova-plugin-xml setVersion",
-    "test": "./node_modules/cordova-paramedic/main.js --plugin . --args=--buildFlag='-UseModernBuildSystem=0' --platform"
+    "test": "npm run eslint",
+    "test-android": "npx cordova-paramedic --platform android --plugin  $(pwd)",
+    "test-appveyor": "npm run test-browser",
+    "test-browser": "npx cordova-paramedic --platform browser --plugin  $(pwd)",
+    "test-ios": "npx cordova-paramedic --platform ios --plugin  $(pwd) --verbose",
+    "test-local": "npm run test-browser && npm run test-android && npm run test-ios",
+    "test-saucelabs": "npm run test-saucelabs-ios && npm run test-saucelabs-android",
+    "test-saucelabs-android": "npx cordova-paramedic --config ./pr/android-7.0 --plugin  $(pwd) --shouldUseSauce",
+    "test-saucelabs-ios": "npx cordova-paramedic --config ./pr/ios-10.0 --plugin  $(pwd) --shouldUseSauce",
+    "test-travis": "npm run test-ios",
+    "test-windows": "npx cordova-paramedic --platform windows --plugin  $(pwd)"
   },
-  "version": "1.7.0"
+  "version": "3.0.1"
 }
index d79cb98..e3d9aef 100644 (file)
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<plugin xmlns="http://apache.org/cordova/ns/plugins/1.0" xmlns:android="http://schemas.android.com/apk/res/android" id="cordova-plugin-fingerprint-aio" version="1.7.0">
+<plugin xmlns="http://apache.org/cordova/ns/plugins/1.0" xmlns:android="http://schemas.android.com/apk/res/android" id="cordova-plugin-fingerprint-aio" version="3.0.1">
   <name>FingerprintAllInOne</name>
   <description>Cordova plugin to use fingerprint on Android and iOS</description>
   <license>MIT</license>
@@ -11,7 +11,6 @@
     <clobbers target="Fingerprint"/>
   </js-module>
 
-  
 
   <!-- ios -->
   <platform name="ios">
@@ -21,7 +20,7 @@
         <param name="ios-package" value="Fingerprint"/>
       </feature>
     </config-file>
-    <header-file src="src/ios/Bridging-Header.h" />
+    <header-file src="src/ios/Bridging-Header.h"/>
     <source-file src="src/ios/Fingerprint.swift"/>
 
     <!-- Usage description of Face ID for iOS 11+ -->
   <platform name="android">
     <config-file target="res/xml/config.xml" parent="/*">
       <feature name="Fingerprint">
-        <param name="android-package" value="de.niklasmerz.cordova.fingerprint.Fingerprint"/>
+        <param name="android-package" value="de.niklasmerz.cordova.biometric.Fingerprint"/>
       </feature>
     </config-file>
+    
     <config-file target="AndroidManifest.xml" parent="/*">
+         <uses-permission android:name="android.permission.USE_BIOMETRIC" />
       <uses-permission android:name="android.permission.USE_FINGERPRINT"/>
     </config-file>
 
-    <source-file src="src/android/Fingerprint.java" target-dir="src/de/niklasmerz/cordova/fingerprint"/>
-    <source-file src="src/android/FingerprintAuthenticationDialogFragment.java" target-dir="src/de/niklasmerz/cordova/fingerprint"/>
-    <source-file src="src/android/FingerprintUiHelper.java" target-dir="src/de/niklasmerz/cordova/fingerprint"/>
-    <source-file src="res/android/drawable/ic_fingerprint_error.xml" target-dir="res/drawable"/>
-    <source-file src="res/android/drawable/ic_fingerprint_success.xml" target-dir="res/drawable"/>
-    <resource-file src="res/android/drawable-hdpi/ic_fp_40px.png" target="res/drawable-hdpi/ic_fp_40px.png"/>
-    <resource-file src="res/android/drawable-mdpi/ic_fp_40px.png" target="res/drawable-mdpi/ic_fp_40px.png"/>
-    <resource-file src="res/android/drawable-nodpi/android_robot.png" target="res/drawable-nodpi/android_robot.png"/>
-    <resource-file src="res/android/drawable-xhdpi/ic_fp_40px.png" target="res/drawable-xhdpi/ic_fp_40px.png"/>
-    <resource-file src="res/android/drawable-xxhdpi/ic_fp_40px.png" target="res/drawable-xxhdpi/ic_fp_40px.png"/>
-    <resource-file src="res/android/drawable-xxxhdpi/ic_fp_40px.png" target="res/drawable-xxxhdpi/ic_fp_40px.png"/>
-    <source-file src="res/android/layout/fingerprint_dialog_container.xml" target-dir="res/layout"/>
-    <source-file src="res/android/layout/fingerprint_dialog_content.xml" target-dir="res/layout"/>
-    <source-file src="res/android/values/fpauth-colors.xml" target-dir="res/values"/>
-    <source-file src="res/android/values/fpauth-strings.xml" target-dir="res/values"/>
-    <source-file src="res/android/values-es/fpauth-strings.xml" target-dir="res/values-es"/>
-    <source-file src="res/android/values-de/fpauth-strings.xml" target-dir="res/values-de"/>
-    <source-file src="res/android/values-fr/fpauth-strings.xml" target-dir="res/values-fr"/>
-    <source-file src="res/android/values-zh/fpauth-strings.xml" target-dir="res/values-zh"/>
-    <source-file src="res/android/values-pt/fpauth-strings.xml" target-dir="res/values-pt"/>
-    <source-file src="res/android/values-it/fpauth-strings.xml" target-dir="res/values-it"/>
-    <source-file src="res/android/values-el/fpauth-strings.xml" target-dir="res/values-el"/>       
-    <source-file src="res/android/values-zh-rTW/fpauth-strings.xml" target-dir="res/values-zh-rTW"/>   
-    <source-file src="res/android/values-nl/fpauth-strings.xml" target-dir="res/values-nl"/>
-    <source-file src="res/android/values-da/fpauth-strings.xml" target-dir="res/values-da"/>
+    <config-file target="AndroidManifest.xml" parent="/manifest/application">
+      <activity
+          android:name="de.niklasmerz.cordova.biometric.BiometricActivity"
+          android:theme="@style/TransparentTheme"
+          android:exported="true" />
+    </config-file>
+    
+    <framework src="src/android/build.gradle" custom="true" type="gradleReference"/>
+    <resource-file src="src/android/res/biometric_activity.xml" target="res/layout/biometric_activity.xml" />
+    <resource-file src="src/android/res/styles.xml" target="res/values/biometric-styles.xml" />
+    <source-file src="src/android/PromptInfo.java" target-dir="src/de/niklasmerz/cordova/biometric"/>
+    <source-file src="src/android/BiometricActivity.java" target-dir="src/de/niklasmerz/cordova/biometric"/>
+    <source-file src="src/android/Fingerprint.java" target-dir="src/de/niklasmerz/cordova/biometric"/>
+    <source-file src="src/android/PluginError.java" target-dir="src/de/niklasmerz/cordova/biometric"/>
   </platform>
 
+  <engines>
+    <engine name="cordova-android" version=">=8.0.0" />
+  </engines>
+
 </plugin>
diff --git a/plugins/cordova-plugin-fingerprint-aio/res/android/drawable-hdpi/ic_fp_40px.png b/plugins/cordova-plugin-fingerprint-aio/res/android/drawable-hdpi/ic_fp_40px.png
deleted file mode 100644 (file)
index 48ebd8a..0000000
Binary files a/plugins/cordova-plugin-fingerprint-aio/res/android/drawable-hdpi/ic_fp_40px.png and /dev/null differ
diff --git a/plugins/cordova-plugin-fingerprint-aio/res/android/drawable-mdpi/ic_fp_40px.png b/plugins/cordova-plugin-fingerprint-aio/res/android/drawable-mdpi/ic_fp_40px.png
deleted file mode 100644 (file)
index 122f442..0000000
Binary files a/plugins/cordova-plugin-fingerprint-aio/res/android/drawable-mdpi/ic_fp_40px.png and /dev/null differ
diff --git a/plugins/cordova-plugin-fingerprint-aio/res/android/drawable-nodpi/android_robot.png b/plugins/cordova-plugin-fingerprint-aio/res/android/drawable-nodpi/android_robot.png
deleted file mode 100644 (file)
index 40bf934..0000000
Binary files a/plugins/cordova-plugin-fingerprint-aio/res/android/drawable-nodpi/android_robot.png and /dev/null differ
diff --git a/plugins/cordova-plugin-fingerprint-aio/res/android/drawable-xhdpi/ic_fp_40px.png b/plugins/cordova-plugin-fingerprint-aio/res/android/drawable-xhdpi/ic_fp_40px.png
deleted file mode 100644 (file)
index e1c9590..0000000
Binary files a/plugins/cordova-plugin-fingerprint-aio/res/android/drawable-xhdpi/ic_fp_40px.png and /dev/null differ
diff --git a/plugins/cordova-plugin-fingerprint-aio/res/android/drawable-xxhdpi/ic_fp_40px.png b/plugins/cordova-plugin-fingerprint-aio/res/android/drawable-xxhdpi/ic_fp_40px.png
deleted file mode 100644 (file)
index f7e8724..0000000
Binary files a/plugins/cordova-plugin-fingerprint-aio/res/android/drawable-xxhdpi/ic_fp_40px.png and /dev/null differ
diff --git a/plugins/cordova-plugin-fingerprint-aio/res/android/drawable-xxxhdpi/ic_fp_40px.png b/plugins/cordova-plugin-fingerprint-aio/res/android/drawable-xxxhdpi/ic_fp_40px.png
deleted file mode 100644 (file)
index 0fb8545..0000000
Binary files a/plugins/cordova-plugin-fingerprint-aio/res/android/drawable-xxxhdpi/ic_fp_40px.png and /dev/null differ
diff --git a/plugins/cordova-plugin-fingerprint-aio/res/android/drawable/ic_fingerprint_error.xml b/plugins/cordova-plugin-fingerprint-aio/res/android/drawable/ic_fingerprint_error.xml
deleted file mode 100644 (file)
index be46116..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  ~ Copyright (C) 2015 The Android Open Source Project
-  ~
-  ~ Licensed under the Apache License, Version 2.0 (the "License");
-  ~ you may not use this file except in compliance with the License.
-  ~ You may obtain a copy of the License at
-  ~
-  ~      http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~ Unless required by applicable law or agreed to in writing, software
-  ~ distributed under the License is distributed on an "AS IS" BASIS,
-  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  ~ See the License for the specific language governing permissions and
-  ~ limitations under the License
-  -->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:width="40.0dp"
-        android:height="40.0dp"
-        android:viewportWidth="40.0"
-        android:viewportHeight="40.0">
-    <path
-        android:pathData="M20.0,0.0C8.96,0.0 0.0,8.95 0.0,20.0s8.96,20.0 20.0,20.0c11.04,0.0 20.0,-8.95 20.0,-20.0S31.04,0.0 20.0,0.0z"
-        android:fillColor="#F4511E"/>
-    <path
-        android:pathData="M21.33,29.33l-2.67,0.0l0.0,-2.67l2.67,0.0L21.33,29.33zM21.33,22.67l-2.67,0.0l0.0,-12.0l2.67,0.0L21.33,22.67z"
-        android:fillColor="#FFFFFF"/>
-</vector>
diff --git a/plugins/cordova-plugin-fingerprint-aio/res/android/drawable/ic_fingerprint_success.xml b/plugins/cordova-plugin-fingerprint-aio/res/android/drawable/ic_fingerprint_success.xml
deleted file mode 100644 (file)
index 261f3e7..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  ~ Copyright (C) 2015 The Android Open Source Project
-  ~
-  ~ Licensed under the Apache License, Version 2.0 (the "License");
-  ~ you may not use this file except in compliance with the License.
-  ~ You may obtain a copy of the License at
-  ~
-  ~      http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~ Unless required by applicable law or agreed to in writing, software
-  ~ distributed under the License is distributed on an "AS IS" BASIS,
-  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  ~ See the License for the specific language governing permissions and
-  ~ limitations under the License
-  -->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:width="40.0dp"
-        android:height="40.0dp"
-        android:viewportWidth="40.0"
-        android:viewportHeight="40.0">
-    <path
-        android:pathData="M20.0,20.0m-20.0,0.0a20.0,20.0 0.0,1.0 1.0,40.0 0.0a20.0,20.0 0.0,1.0 1.0,-40.0 0.0"
-        android:fillColor="#009688"/>
-    <path
-        android:pathData="M11.2,21.41l1.63,-1.619999 4.17,4.169998 10.59,-10.589999 1.619999,1.63 -12.209999,12.209999z"
-        android:fillColor="#FFFFFF"/>
-</vector>
diff --git a/plugins/cordova-plugin-fingerprint-aio/res/android/layout/fingerprint_dialog_container.xml b/plugins/cordova-plugin-fingerprint-aio/res/android/layout/fingerprint_dialog_container.xml
deleted file mode 100644 (file)
index 0c6face..0000000
+++ /dev/null
@@ -1,61 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  ~ Copyright (C) 2015 The Android Open Source Project
-  ~
-  ~ Licensed under the Apache License, Version 2.0 (the "License");
-  ~ you may not use this file except in compliance with the License.
-  ~ You may obtain a copy of the License at
-  ~
-  ~      http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~ Unless required by applicable law or agreed to in writing, software
-  ~ distributed under the License is distributed on an "AS IS" BASIS,
-  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  ~ See the License for the specific language governing permissions and
-  ~ limitations under the License
-  -->
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_width="match_parent"
-    android:layout_height="match_parent"
-    android:orientation="vertical">
-
-    <FrameLayout
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content">
-
-        <include layout="@layout/fingerprint_dialog_content" />
-
-    </FrameLayout>
-
-    <LinearLayout
-        android:id="@+id/buttonPanel"
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:orientation="horizontal"
-        android:paddingStart="12dp"
-        android:paddingEnd="12dp"
-        android:paddingTop="4dp"
-        android:paddingBottom="4dp"
-        android:gravity="bottom"
-        style="?android:attr/buttonBarStyle">
-
-        <Space
-            android:id="@+id/spacer"
-            android:layout_width="0dp"
-            android:layout_height="0dp"
-            android:layout_weight="1"
-            android:visibility="invisible" />
-        <Button
-            android:id="@+id/cancel_button"
-            style="?android:attr/buttonBarNegativeButtonStyle"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"/>
-
-        <Button
-            android:id="@+id/second_dialog_button"
-            style="?android:attr/buttonBarPositiveButtonStyle"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"/>
-    </LinearLayout>
-
-</LinearLayout>
\ No newline at end of file
diff --git a/plugins/cordova-plugin-fingerprint-aio/res/android/layout/fingerprint_dialog_content.xml b/plugins/cordova-plugin-fingerprint-aio/res/android/layout/fingerprint_dialog_content.xml
deleted file mode 100644 (file)
index 3929eba..0000000
+++ /dev/null
@@ -1,58 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  ~ Copyright (C) 2015 The Android Open Source Project
-  ~
-  ~ Licensed under the Apache License, Version 2.0 (the "License");
-  ~ you may not use this file except in compliance with the License.
-  ~ You may obtain a copy of the License at
-  ~
-  ~      http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~ Unless required by applicable law or agreed to in writing, software
-  ~ distributed under the License is distributed on an "AS IS" BASIS,
-  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  ~ See the License for the specific language governing permissions and
-  ~ limitations under the License
-  -->
-<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    android:id="@+id/fingerprint_container"
-    android:layout_width="match_parent"
-    android:layout_height="match_parent"
-    android:paddingBottom="8dp"
-    android:paddingStart="24dp"
-    android:paddingEnd="24dp"
-    android:paddingTop="16dp">
-
-    <TextView
-        android:id="@+id/fingerprint_description"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_alignParentStart="true"
-        android:layout_alignParentTop="true"
-        android:text="@string/fingerprint_description"
-        android:textAppearance="@android:style/TextAppearance.Material.Subhead"
-        android:textColor="?android:attr/textColorSecondary"/>
-
-
-    <ImageView
-        android:id="@+id/fingerprint_icon"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_alignParentStart="true"
-        android:layout_below="@+id/fingerprint_description"
-        android:layout_marginTop="20dp"
-        android:src="@drawable/ic_fp_40px" />
-
-    <TextView
-        android:id="@+id/fingerprint_status"
-        style="@android:style/TextAppearance.Material.Body1"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_alignBottom="@+id/fingerprint_icon"
-        android:layout_alignTop="@+id/fingerprint_icon"
-        android:layout_marginStart="16dp"
-        android:layout_toEndOf="@+id/fingerprint_icon"
-        android:gravity="center_vertical"
-        android:text="@string/fingerprint_hint"
-        android:textColor="@color/hint_color" />
-</RelativeLayout>
\ No newline at end of file
diff --git a/plugins/cordova-plugin-fingerprint-aio/res/android/values-da/fpauth-strings.xml b/plugins/cordova-plugin-fingerprint-aio/res/android/values-da/fpauth-strings.xml
deleted file mode 100644 (file)
index 346666f..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<resources>
-    <string name="fingerprint_cancel">Annuller</string>
-    <string name="fingerprint_use_backup">Brug backup</string>
-    <string name="fingerprint_auth_dialog_title">Fingeraftryk Login</string>
-    <string name="fingerprint_ok">Ok</string>
-    <string name="fingerprint_description">Bekræft fingeraftryk for at fortsætte</string>
-    <string name="fingerprint_hint">Rør sensor</string>
-    <string name="fingerprint_not_recognized">Fingeraftryk ikke genkendt. Prøv igen.</string>
-    <string name="fingerprint_success">Fingeraftryk godkendt</string>
-    <string name="new_fingerprint_enrolled_description">Et nyt fingeraftryk blev tilføjet til denne enhed så din adgangskode er krævet.</string>
-    <string name="secure_lock_screen_required">Sikring af skærmlås krævet!</string>
-</resources>
diff --git a/plugins/cordova-plugin-fingerprint-aio/res/android/values-de/fpauth-strings.xml b/plugins/cordova-plugin-fingerprint-aio/res/android/values-de/fpauth-strings.xml
deleted file mode 100644 (file)
index d5b6bd2..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  ~ Copyright (C) 2015 The Android Open Source Project
-  ~
-  ~ Licensed under the Apache License, Version 2.0 (the "License");
-  ~ you may not use this file except in compliance with the License.
-  ~ You may obtain a copy of the License at
-  ~
-  ~      http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~ Unless required by applicable law or agreed to in writing, software
-  ~ distributed under the License is distributed on an "AS IS" BASIS,
-  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  ~ See the License for the specific language governing permissions and
-  ~ limitations under the License
-  -->
-<resources>
-    <string name="fingerprint_cancel">Abbrechen</string>
-    <string name="fingerprint_use_backup">Passwort</string>
-    <string name="fingerprint_auth_dialog_title">Authentifizierung</string>
-    <string name="fingerprint_ok">OK</string>
-    <string name="fingerprint_description">Fingerabdruck bestätigen</string>
-    <string name="fingerprint_hint">Fingerabdrucksensor</string>
-    <string name="fingerprint_not_recognized">Fingerabdruck nicht erkannt. Versuchen Sie es erneut</string>
-    <string name="fingerprint_success">Authentifiziert</string>
-    <string name="new_fingerprint_enrolled_description">Ein neuer Fingerabdruck wurde gespeichert. Bitte geben Sie ihr Passwort ein.</string>
-    <string name="secure_lock_screen_required">Passwortgeschützter Sperrbildschirm benötigt</string>
-</resources>
diff --git a/plugins/cordova-plugin-fingerprint-aio/res/android/values-el/fpauth-strings.xml b/plugins/cordova-plugin-fingerprint-aio/res/android/values-el/fpauth-strings.xml
deleted file mode 100644 (file)
index 1dcfcdb..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<resources>
-    <string name="fingerprint_cancel">Ακύρωση</string>
-    <string name="fingerprint_use_backup">Χρήση αρχείου</string>
-    <string name="fingerprint_auth_dialog_title">Ελεγχος αποτυπώματος</string>
-    <string name="fingerprint_ok">Ok</string>
-    <string name="fingerprint_description">Επιβεβαίωση αποτυπώματος</string>
-    <string name="fingerprint_hint">Αιθηστήρας αφής</string>
-    <string name="fingerprint_not_recognized">Σφάλμα. Προσπαθήστε ξανά</string>
-    <string name="fingerprint_success">Σωστό αποτύπωμα</string>
-    <string name="new_fingerprint_enrolled_description">Νεο αποτύπωμα προστέθηκε , απαιτείται ο κωδικός σας.</string>
-    <string name="secure_lock_screen_required">Απαιτείται κλειδωμα οθόνης</string>
-</resources>
diff --git a/plugins/cordova-plugin-fingerprint-aio/res/android/values-es/fpauth-strings.xml b/plugins/cordova-plugin-fingerprint-aio/res/android/values-es/fpauth-strings.xml
deleted file mode 100644 (file)
index 25bdbb2..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  ~ Copyright (C) 2015 The Android Open Source Project
-  ~
-  ~ Licensed under the Apache License, Version 2.0 (the "License");
-  ~ you may not use this file except in compliance with the License.
-  ~ You may obtain a copy of the License at
-  ~
-  ~      http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~ Unless required by applicable law or agreed to in writing, software
-  ~ distributed under the License is distributed on an "AS IS" BASIS,
-  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  ~ See the License for the specific language governing permissions and
-  ~ limitations under the License
-  -->
-<resources>
-    <string name="fingerprint_cancel">Cancelar</string>
-    <string name="fingerprint_use_backup">El Respaldo</string>
-    <string name="fingerprint_auth_dialog_title">Autenticación de Huellas Digitales</string>
-    <string name="fingerprint_ok">De Acuerdo</string>
-    <string name="fingerprint_description">Confirmar la huella digital para continuar</string>
-    <string name="fingerprint_hint">Sensor tactil</string>
-    <string name="fingerprint_not_recognized">No se reconoce la huella digital. Inténtalo de nuevo.</string>
-    <string name="fingerprint_success">Reconocido de huella dactilar</string>
-    <string name="new_fingerprint_enrolled_description">Una nueva huella digital fue agregada a este dispositivo, por lo que se requiere la contraseña.</string>
-    <string name="secure_lock_screen_required">¡Requiere pantalla de bloqueo seguro!</string>
-</resources>
diff --git a/plugins/cordova-plugin-fingerprint-aio/res/android/values-fr/fpauth-strings.xml b/plugins/cordova-plugin-fingerprint-aio/res/android/values-fr/fpauth-strings.xml
deleted file mode 100644 (file)
index 4b9d3eb..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  ~ Copyright (C) 2015 The Android Open Source Project
-  ~
-  ~ Licensed under the Apache License, Version 2.0 (the "License");
-  ~ you may not use this file except in compliance with the License.
-  ~ You may obtain a copy of the License at
-  ~
-  ~      http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~ Unless required by applicable law or agreed to in writing, software
-  ~ distributed under the License is distributed on an "AS IS" BASIS,
-  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  ~ See the License for the specific language governing permissions and
-  ~ limitations under the License
-  -->
-<resources>
-    <string name="fingerprint_cancel">Annuler</string>
-    <string name="fingerprint_use_backup">Utiliser la sauvegarde</string>
-    <string name="fingerprint_auth_dialog_title">Authentification par empreinte digitale</string>
-    <string name="fingerprint_ok">Ok</string>
-    <string name="fingerprint_description">Confirmer l\'empreinte pour continuer</string>
-    <string name="fingerprint_hint">Toucher le capteur</string>
-    <string name="fingerprint_not_recognized">Empreinte non reconnue. Essayer à nouveau.</string>
-    <string name="fingerprint_success">Empreinte reconnue</string>
-    <string name="new_fingerprint_enrolled_description">Une nouvelle empreinte digitale a été ajoutée à ce dispositif, de sorte que votre mot de passe est nécessaire.</string>
-    <string name="secure_lock_screen_required">Écran de verrouillage sécurisé nécessaire!</string>
-</resources>
diff --git a/plugins/cordova-plugin-fingerprint-aio/res/android/values-it/fpauth-strings.xml b/plugins/cordova-plugin-fingerprint-aio/res/android/values-it/fpauth-strings.xml
deleted file mode 100644 (file)
index a226ff8..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<resources>
-    <string name="fingerprint_cancel">Cancella</string>
-    <string name="fingerprint_use_backup">Usa backup</string>
-    <string name="fingerprint_auth_dialog_title">Autenticazione impronta digitale</string>
-    <string name="fingerprint_ok">Ok</string>
-    <string name="fingerprint_description">Conferma l\'impronta digitale per continuare</string>
-    <string name="fingerprint_hint">Sensore Touch</string>
-    <string name="fingerprint_not_recognized">Impronta digitale non riconosciuta. Riprova.</string>
-    <string name="fingerprint_success">Impronta digitale riconosciuta</string>
-    <string name="new_fingerprint_enrolled_description">Una nuova impronta è stata aggiunta a questo dispositivo, quindi è necessaria la tua password</string>
-    <string name="secure_lock_screen_required">Blocco schermo richiesto!</string>
-</resources>
diff --git a/plugins/cordova-plugin-fingerprint-aio/res/android/values-nl/fpauth-strings.xml b/plugins/cordova-plugin-fingerprint-aio/res/android/values-nl/fpauth-strings.xml
deleted file mode 100644 (file)
index e44731c..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-<resources>
-    <string name="fingerprint_cancel">Annuleer</string>
-    <string name="fingerprint_use_backup">Back-up gebruiken</string>
-    <string name="fingerprint_auth_dialog_title">Authenticatie met vingerafdruk</string>
-    <string name="fingerprint_ok">OK</string>
-    <string name="fingerprint_description">Vingerafdruk bevestigen om verder te gaan</string>
-    <string name="fingerprint_hint">Aanraaksensor</string>
-    <string name="fingerprint_not_recognized">Vingerafdruk niet herkend.Opnieuw proberen.</string>
-    <string name="fingerprint_success">Vingerafdruk herkend</string>
-    <string name="new_fingerprint_enrolled_description">Er werd een nieuwe vingerafdruk aan dit apparaat toegevoegd, waardoor uw wachtwoord is vereist.</string>
-    <string name="secure_lock_screen_required">Beveiligd vergrendelingsscherm vereist!</string>
-</resources>
diff --git a/plugins/cordova-plugin-fingerprint-aio/res/android/values-pt/fpauth-strings.xml b/plugins/cordova-plugin-fingerprint-aio/res/android/values-pt/fpauth-strings.xml
deleted file mode 100644 (file)
index 7c3e581..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<resources>
-    <string name="fingerprint_cancel">Cancelar</string>
-    <string name="fingerprint_use_backup">Use o backup</string>
-    <string name="fingerprint_auth_dialog_title">Autenticação de impressão digital</string>
-    <string name="fingerprint_ok">Ok</string>
-    <string name="fingerprint_description">Confirme a impressão digital para continuar</string>
-    <string name="fingerprint_hint">Sensor de toque</string>
-    <string name="fingerprint_not_recognized">impressão digital não reconhecida. Tente novamente.</string>
-    <string name="fingerprint_success">impressão digital reconhecida</string>
-    <string name="new_fingerprint_enrolled_description">Uma nova impressão digital foi adicionada a este dispositivo, é necessário o seu código</string>
-    <string name="secure_lock_screen_required">É necessário um ecrã de bloqueio seguro!</string>
-</resources>
diff --git a/plugins/cordova-plugin-fingerprint-aio/res/android/values-zh-rTW/fpauth-strings.xml b/plugins/cordova-plugin-fingerprint-aio/res/android/values-zh-rTW/fpauth-strings.xml
deleted file mode 100644 (file)
index c8345a3..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<resources>
-  <string name="fingerprint_cancel">取消</string>
-  <string name="fingerprint_use_backup">使用手勢密碼</string>
-  <string name="fingerprint_auth_dialog_title">指紋識別</string>
-  <string name="fingerprint_ok">確認</string><string name="fingerprint_description">指紋識別</string>
-  <string name="fingerprint_hint">請觸摸指紋識別傳感器</string>
-  <string name="fingerprint_not_recognized">指紋無法識別,請再試一次</string>
-  <string name="fingerprint_success">指紋識別成功</string>
-  <string name="new_fingerprint_enrolled_description">添加一個新的指紋,需要設置密碼</string>
-  <string name="secure_lock_screen_required">需要安全鎖屏</string>
-</resources>
diff --git a/plugins/cordova-plugin-fingerprint-aio/res/android/values-zh/fpauth-strings.xml b/plugins/cordova-plugin-fingerprint-aio/res/android/values-zh/fpauth-strings.xml
deleted file mode 100644 (file)
index 54d38b7..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<resources>
-  <string name="fingerprint_cancel">取消</string>
-  <string name="fingerprint_use_backup">使用手势密码</string>
-  <string name="fingerprint_auth_dialog_title">指纹识别</string>
-  <string name="fingerprint_ok">确认</string><string name="fingerprint_description">指纹识别</string>
-  <string name="fingerprint_hint">请触摸指纹识传感器</string>
-  <string name="fingerprint_not_recognized">指纹无法识别,请再试一次</string>
-  <string name="fingerprint_success">指纹识别成功</string>
-  <string name="new_fingerprint_enrolled_description">添加一个新的指纹,需要设置密码</string>
-  <string name="secure_lock_screen_required">需要安全锁屏</string>
-</resources>
\ No newline at end of file
diff --git a/plugins/cordova-plugin-fingerprint-aio/res/android/values/fpauth-colors.xml b/plugins/cordova-plugin-fingerprint-aio/res/android/values/fpauth-colors.xml
deleted file mode 100644 (file)
index a24f3c8..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  ~ Copyright (C) 2015 The Android Open Source Project
-  ~
-  ~ Licensed under the Apache License, Version 2.0 (the "License");
-  ~ you may not use this file except in compliance with the License.
-  ~ You may obtain a copy of the License at
-  ~
-  ~      http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~ Unless required by applicable law or agreed to in writing, software
-  ~ distributed under the License is distributed on an "AS IS" BASIS,
-  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  ~ See the License for the specific language governing permissions and
-  ~ limitations under the License
-  -->
-<resources>
-    <color name="warning_color">#f4511e</color>
-    <color name="hint_color">#42000000</color>
-    <color name="success_color">#009688</color>
-</resources>
diff --git a/plugins/cordova-plugin-fingerprint-aio/res/android/values/fpauth-strings.xml b/plugins/cordova-plugin-fingerprint-aio/res/android/values/fpauth-strings.xml
deleted file mode 100644 (file)
index 00cc755..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  ~ Copyright (C) 2015 The Android Open Source Project
-  ~
-  ~ Licensed under the Apache License, Version 2.0 (the "License");
-  ~ you may not use this file except in compliance with the License.
-  ~ You may obtain a copy of the License at
-  ~
-  ~      http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~ Unless required by applicable law or agreed to in writing, software
-  ~ distributed under the License is distributed on an "AS IS" BASIS,
-  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  ~ See the License for the specific language governing permissions and
-  ~ limitations under the License
-  -->
-<resources>
-    <string name="fingerprint_cancel">Cancel</string>
-    <string name="fingerprint_use_backup">Use backup</string>
-    <string name="fingerprint_auth_dialog_title">Fingerprint Authentication</string>
-    <string name="fingerprint_ok">Ok</string>
-    <string name="fingerprint_description">Confirm fingerprint to continue</string>
-    <string name="fingerprint_hint">Touch sensor</string>
-    <string name="fingerprint_not_recognized">Fingerprint not recognized. Try again.</string>
-    <string name="fingerprint_success">Fingerprint recognized</string>
-    <string name="new_fingerprint_enrolled_description">A new fingerprint was added to this device, so your password is required.</string>
-    <string name="secure_lock_screen_required">Secure lock screen required!</string>
-</resources>
diff --git a/plugins/cordova-plugin-fingerprint-aio/src/android/.gradle/6.0-20191016123526+0000/fileChanges/last-build.bin b/plugins/cordova-plugin-fingerprint-aio/src/android/.gradle/6.0-20191016123526+0000/fileChanges/last-build.bin
new file mode 100644 (file)
index 0000000..f76dd23
Binary files /dev/null and b/plugins/cordova-plugin-fingerprint-aio/src/android/.gradle/6.0-20191016123526+0000/fileChanges/last-build.bin differ
diff --git a/plugins/cordova-plugin-fingerprint-aio/src/android/.gradle/6.0-20191016123526+0000/fileHashes/fileHashes.lock b/plugins/cordova-plugin-fingerprint-aio/src/android/.gradle/6.0-20191016123526+0000/fileHashes/fileHashes.lock
new file mode 100644 (file)
index 0000000..106dd85
Binary files /dev/null and b/plugins/cordova-plugin-fingerprint-aio/src/android/.gradle/6.0-20191016123526+0000/fileHashes/fileHashes.lock differ
diff --git a/plugins/cordova-plugin-fingerprint-aio/src/android/.gradle/6.0-20191016123526+0000/gc.properties b/plugins/cordova-plugin-fingerprint-aio/src/android/.gradle/6.0-20191016123526+0000/gc.properties
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/plugins/cordova-plugin-fingerprint-aio/src/android/.gradle/buildOutputCleanup/buildOutputCleanup.lock b/plugins/cordova-plugin-fingerprint-aio/src/android/.gradle/buildOutputCleanup/buildOutputCleanup.lock
new file mode 100644 (file)
index 0000000..2c45a25
Binary files /dev/null and b/plugins/cordova-plugin-fingerprint-aio/src/android/.gradle/buildOutputCleanup/buildOutputCleanup.lock differ
diff --git a/plugins/cordova-plugin-fingerprint-aio/src/android/.gradle/buildOutputCleanup/cache.properties b/plugins/cordova-plugin-fingerprint-aio/src/android/.gradle/buildOutputCleanup/cache.properties
new file mode 100644 (file)
index 0000000..34f1943
--- /dev/null
@@ -0,0 +1,2 @@
+#Sat Nov 16 11:08:08 CET 2019
+gradle.version=6.0-20191016123526+0000
diff --git a/plugins/cordova-plugin-fingerprint-aio/src/android/.gradle/vcs-1/gc.properties b/plugins/cordova-plugin-fingerprint-aio/src/android/.gradle/vcs-1/gc.properties
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/plugins/cordova-plugin-fingerprint-aio/src/android/.project b/plugins/cordova-plugin-fingerprint-aio/src/android/.project
new file mode 100644 (file)
index 0000000..3964dd3
--- /dev/null
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+       <name>android</name>
+       <comment>Project android created by Buildship.</comment>
+       <projects>
+       </projects>
+       <buildSpec>
+               <buildCommand>
+                       <name>org.eclipse.buildship.core.gradleprojectbuilder</name>
+                       <arguments>
+                       </arguments>
+               </buildCommand>
+       </buildSpec>
+       <natures>
+               <nature>org.eclipse.buildship.core.gradleprojectnature</nature>
+       </natures>
+</projectDescription>
diff --git a/plugins/cordova-plugin-fingerprint-aio/src/android/.settings/org.eclipse.buildship.core.prefs b/plugins/cordova-plugin-fingerprint-aio/src/android/.settings/org.eclipse.buildship.core.prefs
new file mode 100644 (file)
index 0000000..39c6821
--- /dev/null
@@ -0,0 +1,13 @@
+arguments=
+auto.sync=false
+build.scans.enabled=false
+connection.gradle.distribution=GRADLE_DISTRIBUTION(VERSION(6.0-20191016123526+0000))
+connection.project.dir=
+eclipse.preferences.version=1
+gradle.user.home=
+java.home=
+jvm.arguments=
+offline.mode=false
+override.workspace.settings=true
+show.console.view=true
+show.executions.view=true
diff --git a/plugins/cordova-plugin-fingerprint-aio/src/android/BiometricActivity.java b/plugins/cordova-plugin-fingerprint-aio/src/android/BiometricActivity.java
new file mode 100644 (file)
index 0000000..0d6d20e
--- /dev/null
@@ -0,0 +1,159 @@
+package de.niklasmerz.cordova.biometric;
+
+import android.app.Activity;
+import android.app.KeyguardManager;
+import android.content.Intent;
+import android.os.Build;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Looper;
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
+import android.support.v4.content.ContextCompat;
+import android.support.v7.app.AppCompatActivity;
+
+import com.exxbrain.android.biometric.BiometricPrompt;
+
+import java.util.concurrent.Executor;
+
+public class BiometricActivity extends AppCompatActivity {
+
+    private static final int REQUEST_CODE_CONFIRM_DEVICE_CREDENTIALS = 2;
+    private PromptInfo mPromptInfo;
+
+    @Override
+    protected void onCreate(@Nullable Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        setTitle(null);
+        int layout = getResources()
+                .getIdentifier("biometric_activity", "layout", getPackageName());
+        setContentView(layout);
+
+        if (savedInstanceState != null) {
+            return;
+        }
+
+        mPromptInfo = new PromptInfo.Builder(getIntent().getExtras()).build();
+        authenticate();
+
+    }
+
+    private void authenticate() {
+        final Handler handler = new Handler(Looper.getMainLooper());
+        Executor executor = handler::post;
+
+        BiometricPrompt biometricPrompt =
+                new BiometricPrompt(this, executor, mAuthenticationCallback);
+
+        BiometricPrompt.PromptInfo.Builder promptInfoBuilder = new BiometricPrompt.PromptInfo.Builder()
+                .setTitle(mPromptInfo.getTitle())
+                .setSubtitle(mPromptInfo.getSubtitle())
+                .setDescription(mPromptInfo.getDescription());
+
+        if (mPromptInfo.isDeviceCredentialAllowed()
+                && Build.VERSION.SDK_INT <= Build.VERSION_CODES.P) { // TODO: remove after fix https://issuetracker.google.com/issues/142740104
+            promptInfoBuilder.setDeviceCredentialAllowed(true);
+        } else {
+            promptInfoBuilder.setNegativeButtonText(mPromptInfo.getCancelButtonTitle());
+        }
+
+        biometricPrompt.authenticate(promptInfoBuilder.build());
+    }
+
+    private BiometricPrompt.AuthenticationCallback mAuthenticationCallback =
+            new BiometricPrompt.AuthenticationCallback() {
+
+                @Override
+                public void onAuthenticationError(int errorCode, @NonNull CharSequence errString) {
+                    super.onAuthenticationError(errorCode, errString);
+                    onError(errorCode, errString);
+                }
+
+                @Override
+                public void onAuthenticationSucceeded(@NonNull BiometricPrompt.AuthenticationResult result) {
+                    super.onAuthenticationSucceeded(result);
+                    finishWithSuccess();
+                }
+
+                @Override
+                public void onAuthenticationFailed() {
+                    super.onAuthenticationFailed();
+                }
+            };
+
+
+    // TODO: remove after fix https://issuetracker.google.com/issues/142740104
+    private void showAuthenticationScreen() {
+        KeyguardManager keyguardManager = ContextCompat
+                .getSystemService(this, KeyguardManager.class);
+        if (keyguardManager == null
+                || android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.LOLLIPOP) {
+            return;
+        }
+        if (keyguardManager.isKeyguardSecure()) {
+            Intent intent = keyguardManager
+                    .createConfirmDeviceCredentialIntent(mPromptInfo.getTitle(), mPromptInfo.getDescription());
+            this.startActivityForResult(intent, REQUEST_CODE_CONFIRM_DEVICE_CREDENTIALS);
+        } else {
+            // Show a message that the user hasn't set up a lock screen.
+            finishWithError(PluginError.BIOMETRIC_SCREEN_GUARD_UNSECURED);
+        }
+    }
+
+    // TODO: remove after fix https://issuetracker.google.com/issues/142740104
+    @Override
+    public void onActivityResult(int requestCode, int resultCode, Intent data) {
+        if (requestCode == REQUEST_CODE_CONFIRM_DEVICE_CREDENTIALS) {
+            if (resultCode == Activity.RESULT_OK) {
+                finishWithSuccess();
+            } else {
+                finishWithError(PluginError.BIOMETRIC_PIN_OR_PATTERN_DISMISSED);
+            }
+        }
+    }
+
+    private void onError(int errorCode, @NonNull CharSequence errString) {
+
+        switch (errorCode)
+        {
+            case BiometricPrompt.ERROR_USER_CANCELED:
+            case BiometricPrompt.ERROR_CANCELED:
+                finishWithError(PluginError.BIOMETRIC_DISMISSED);
+                return;
+            case BiometricPrompt.ERROR_NEGATIVE_BUTTON:
+                // TODO: remove after fix https://issuetracker.google.com/issues/142740104
+                if (Build.VERSION.SDK_INT > Build.VERSION_CODES.P && mPromptInfo.isDeviceCredentialAllowed()) {
+                    showAuthenticationScreen();
+                    return;
+                }
+                finishWithError(PluginError.BIOMETRIC_DISMISSED);
+                break;
+            case BiometricPrompt.ERROR_LOCKOUT:
+                finishWithError(PluginError.BIOMETRIC_LOCKED_OUT.getValue(), errString.toString());
+                break;
+            case BiometricPrompt.ERROR_LOCKOUT_PERMANENT:
+                finishWithError(PluginError.BIOMETRIC_LOCKED_OUT_PERMANENT.getValue(), errString.toString());
+                break;
+            default:
+                finishWithError(errorCode, errString.toString());
+        }
+    }
+
+    private void finishWithSuccess() {
+        setResult(RESULT_OK);
+        finish();
+    }
+
+    private void finishWithError(PluginError error) {
+        finishWithError(error.getValue(), error.getMessage());
+    }
+
+    private void finishWithError(int code, String message) {
+        Intent data = new Intent();
+        data.putExtra("code", code);
+        data.putExtra("message", message);
+        setResult(RESULT_CANCELED, data);
+        finish();
+    }
+}
index 32fd67c..5bfe78e 100644 (file)
-/*
- * Copyright (C) https://github.com/mjwheatley/cordova-plugin-android-fingerprint-auth
- * Modifications copyright (C) 2016 Niklas Merz
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
+package de.niklasmerz.cordova.biometric;
 
-package de.niklasmerz.cordova.fingerprint;
-
-import org.apache.cordova.CordovaWebView;
-import org.apache.cordova.CallbackContext;
-import org.apache.cordova.CordovaPlugin;
-import org.apache.cordova.CordovaInterface;
-
-import android.annotation.TargetApi;
-import android.app.FragmentTransaction;
-import android.app.KeyguardManager;
-import android.content.res.Configuration;
-import android.content.res.Resources;
-import android.hardware.fingerprint.FingerprintManager;
+import android.app.Activity;
+import android.content.Intent;
+import android.os.Build;
 import android.os.Bundle;
-import android.security.keystore.KeyGenParameterSpec;
-import android.security.keystore.KeyPermanentlyInvalidatedException;
-import android.security.keystore.KeyProperties;
-import android.util.Base64;
-import android.util.DisplayMetrics;
 import android.util.Log;
 
+import com.exxbrain.android.biometric.BiometricManager;
+
+import org.apache.cordova.CallbackContext;
+import org.apache.cordova.CordovaInterface;
+import org.apache.cordova.CordovaPlugin;
+import org.apache.cordova.CordovaWebView;
 import org.apache.cordova.PluginResult;
 import org.json.JSONArray;
 import org.json.JSONException;
 import org.json.JSONObject;
 
-import java.io.IOException;
-import java.security.InvalidAlgorithmParameterException;
-import java.security.InvalidKeyException;
-import java.security.KeyStore;
-import java.security.KeyStoreException;
-import java.security.NoSuchAlgorithmException;
-import java.security.NoSuchProviderException;
-import java.security.UnrecoverableKeyException;
-import java.security.cert.CertificateException;
-import java.util.Locale;
-
-import javax.crypto.BadPaddingException;
-import javax.crypto.Cipher;
-import javax.crypto.IllegalBlockSizeException;
-import javax.crypto.KeyGenerator;
-import javax.crypto.NoSuchPaddingException;
-import javax.crypto.SecretKey;
-
-@TargetApi(23)
 public class Fingerprint extends CordovaPlugin {
 
-    public static final String TAG = "Fingerprint";
-    public static String packageName;
-
-    private static final String DIALOG_FRAGMENT_TAG = "FpAuthDialog";
-    private static final String ANDROID_KEY_STORE = "AndroidKeyStore";
+    private static final String TAG = "Fingerprint";
+    private CallbackContext mCallbackContext = null;
 
-    KeyguardManager mKeyguardManager;
-    FingerprintAuthenticationDialogFragment mFragment;
-    public static KeyStore mKeyStore;
-    public static KeyGenerator mKeyGenerator;
-    public static Cipher mCipher;
-    private FingerprintManager mFingerPrintManager;
-
-    public static CallbackContext mCallbackContext;
-    public static PluginResult mPluginResult;
-
-    /**
-     * Alias for our key in the Android Key Store
-     */
-    private static String mClientId;
-    /**
-     * Used to encrypt token
-     */
-    private static String mClientSecret;
-
-    /**
-     * Options
-     */
-    private static boolean mDisableBackup = false;
-
-    /**
-     * Constructor.
-     */
-    public Fingerprint() {
-    }
-
-    /**
-     * Sets the context of the Command. This can then be used to do things like
-     * get file paths associated with the Activity.
-     *
-     * @param cordova The context of the main Activity.
-     * @param webView The CordovaWebView Cordova is running in.
-     */
+    private static final int REQUEST_CODE_BIOMETRIC = 1;
+    private PromptInfo.Builder mPromptInfoBuilder;
 
     public void initialize(CordovaInterface cordova, CordovaWebView webView) {
         super.initialize(cordova, webView);
         Log.v(TAG, "Init Fingerprint");
-        packageName = cordova.getActivity().getApplicationContext().getPackageName();
-        mPluginResult = new PluginResult(PluginResult.Status.NO_RESULT);
-
-        if (android.os.Build.VERSION.SDK_INT < 23) {
-            return;
-        }
-
-        mKeyguardManager = cordova.getActivity().getSystemService(KeyguardManager.class);
-        mFingerPrintManager = cordova.getActivity().getApplicationContext()
-                .getSystemService(FingerprintManager.class);
-
-        try {
-            mKeyGenerator = KeyGenerator.getInstance(
-                    KeyProperties.KEY_ALGORITHM_AES, ANDROID_KEY_STORE);
-            mKeyStore = KeyStore.getInstance(ANDROID_KEY_STORE);
-
-        } catch (NoSuchAlgorithmException e) {
-            throw new RuntimeException("Failed to get an instance of KeyGenerator", e);
-        } catch (NoSuchProviderException e) {
-            throw new RuntimeException("Failed to get an instance of KeyGenerator", e);
-        } catch (KeyStoreException e) {
-            throw new RuntimeException("Failed to get an instance of KeyStore", e);
-        }
-
-        try {
-            mCipher = Cipher.getInstance(KeyProperties.KEY_ALGORITHM_AES + "/"
-                    + KeyProperties.BLOCK_MODE_CBC + "/"
-                    + KeyProperties.ENCRYPTION_PADDING_PKCS7);
-        } catch (NoSuchAlgorithmException e) {
-            throw new RuntimeException("Failed to get an instance of Cipher", e);
-        } catch (NoSuchPaddingException e) {
-            throw new RuntimeException("Failed to get an instance of Cipher", e);
-        }
+        mPromptInfoBuilder = new PromptInfo.Builder(cordova.getActivity());
     }
 
-    /**
-     * Executes the request and returns PluginResult.
-     *
-     * @param action          The action to execute.
-     * @param args            JSONArry of arguments for the plugin.
-     * @param callbackContext The callback id used when calling back into JavaScript.
-     * @return A PluginResult object with a status and message.
-     */
-    public boolean execute(final String action,
-                           JSONArray args,
-                           CallbackContext callbackContext) throws JSONException {
-        mCallbackContext = callbackContext;
-        Log.v(TAG, "Fingerprint action: " + action);
-        if (android.os.Build.VERSION.SDK_INT < 23) {
-            Log.e(TAG, "minimum SDK version 23 required");
-            mPluginResult = new PluginResult(PluginResult.Status.ERROR);
-            mCallbackContext.error("minimum SDK version 23 required");
-            mCallbackContext.sendPluginResult(mPluginResult);
-            return true;
-        }
+    public boolean execute(final String action, JSONArray args, CallbackContext callbackContext) {
 
-        final JSONObject arg_object = args.getJSONObject(0);
+        this.mCallbackContext = callbackContext;
+        Log.v(TAG, "Fingerprint action: " + action);
 
         if (action.equals("authenticate")) {
-            if (!arg_object.has("clientId") || !arg_object.has("clientSecret")) {
-                mPluginResult = new PluginResult(PluginResult.Status.ERROR);
-                mCallbackContext.error("Missing required parameters");
-                mCallbackContext.sendPluginResult(mPluginResult);
-                return true;
-            }
-            mClientId = arg_object.getString("clientId");
-            mClientSecret = arg_object.getString("clientSecret");
-            if (arg_object.has("disableBackup")) {
-                mDisableBackup = arg_object.getBoolean("disableBackup");
-            }
-            // Set language
-            Resources res = cordova.getActivity().getResources();
-            // Change locale settings in the app.
-            DisplayMetrics dm = res.getDisplayMetrics();
-            Configuration conf = res.getConfiguration();
-            //Do not change locale
-            res.updateConfiguration(conf, dm);
-
-            if (isFingerprintAuthAvailable()) {
-                SecretKey key = getSecretKey();
-                boolean isCipherInit = true;
-                if (key == null) {
-                    if (createKey()) {
-                        key = getSecretKey();
-                    }
-                }
-                if (key != null && !initCipher()) {
-                    isCipherInit = false;
-                }
-                if (key != null) {
-                    cordova.getActivity().runOnUiThread(new Runnable() {
-                        public void run() {
-                            // Set up the crypto object for later. The object will be authenticated by use
-                            // of the fingerprint.
-                            mFragment = new FingerprintAuthenticationDialogFragment();
-                            Bundle bundle = new Bundle();
-                            bundle.putBoolean("disableBackup", mDisableBackup);
-                            mFragment.setArguments(bundle);
-
-                            if (initCipher()) {
-                                mFragment.setCancelable(false);
-                                // Show the fingerprint dialog. The user has the option to use the fingerprint with
-                                // crypto, or you can fall back to using a server-side verified password.
-                                mFragment.setCryptoObject(new FingerprintManager.CryptoObject(mCipher));
-                                FragmentTransaction transaction = cordova.getActivity().getFragmentManager().beginTransaction();
-                                transaction.add(mFragment, DIALOG_FRAGMENT_TAG);
-                                transaction.commitAllowingStateLoss();
-                            } else {
-                                if (!mDisableBackup) {
-                                    // This happens if the lock screen has been disabled or or a fingerprint got
-                                    // enrolled. Thus show the dialog to authenticate with their password
-                                    mFragment.setCryptoObject(new FingerprintManager
-                                            .CryptoObject(mCipher));
-                                    mFragment.setStage(FingerprintAuthenticationDialogFragment
-                                            .Stage.NEW_FINGERPRINT_ENROLLED);
-                                    FragmentTransaction transaction = cordova.getActivity().getFragmentManager().beginTransaction();
-                                    transaction.add(mFragment, DIALOG_FRAGMENT_TAG);
-                                    transaction.commitAllowingStateLoss();
-                                } else {
-                                    mCallbackContext.error("Failed to init Cipher and backup disabled.");
-                                    mPluginResult = new PluginResult(PluginResult.Status.ERROR);
-                                    mCallbackContext.sendPluginResult(mPluginResult);
-                                }
-                            }
-                        }
-                    });
-                    mPluginResult.setKeepCallback(true);
-                } else {
-                    mCallbackContext.sendPluginResult(mPluginResult);
-                }
-
-            } else {
-                mPluginResult = new PluginResult(PluginResult.Status.ERROR);
-                mCallbackContext.error("Fingerprint authentication not available");
-                mCallbackContext.sendPluginResult(mPluginResult);
-            }
+            executeAuthenticate(args);
             return true;
-        } else if (action.equals("isAvailable")) {
-            if(isFingerprintAuthAvailable() && mFingerPrintManager.isHardwareDetected() && mFingerPrintManager.hasEnrolledFingerprints()){
-              mPluginResult = new PluginResult(PluginResult.Status.OK, "finger");
-              mCallbackContext.success("finger");
-            }else{
-              mPluginResult = new PluginResult(PluginResult.Status.ERROR);
 
-              if (mFingerPrintManager.isHardwareDetected() && !mFingerPrintManager.hasEnrolledFingerprints()) {
-                mCallbackContext.error("Fingerprint authentication not ready");
-              } else {
-                mCallbackContext.error("Fingerprint authentication not available");
-              }
-            }
-            mCallbackContext.sendPluginResult(mPluginResult);
+        } else if (action.equals("isAvailable")){
+            executeIsAvailable();
             return true;
         }
+
         return false;
     }
 
-    private boolean isFingerprintAuthAvailable() {
-        return mFingerPrintManager.isHardwareDetected()
-                && mFingerPrintManager.hasEnrolledFingerprints();
+    private void executeIsAvailable() {
+        PluginError error = canAuthenticate();
+        if (error != null) {
+            sendError(error);
+        } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P){
+            sendSuccess("biometric");
+        } else {
+            sendSuccess("finger");
+        }
     }
 
-    /**
-     * Initialize the {@link Cipher} instance with the created key in the {@link #createKey()}
-     * method.
-     *
-     * @return {@code true} if initialization is successful, {@code false} if the lock screen has
-     * been disabled or reset after the key was generated, or if a fingerprint got enrolled after
-     * the key was generated.
-     */
-    private static boolean initCipher() {
-        boolean initCipher = false;
-        String errorMessage = "";
-        String initCipherExceptionErrorPrefix = "Failed to init Cipher: ";
-        try {
-            SecretKey key = getSecretKey();
-            mCipher.init(Cipher.ENCRYPT_MODE, key);
-            initCipher = true;
-        } catch (InvalidKeyException e) {
-            errorMessage = initCipherExceptionErrorPrefix + "InvalidKeyException: " + e.toString();
-            
-        }
-        if (!initCipher) {
-            Log.e(TAG, errorMessage);
-            createKey();
+    private void executeAuthenticate(JSONArray args) {
+        PluginError error = canAuthenticate();
+        if (error != null) {
+            sendError(error);
+            return;
         }
-        return initCipher;
+        cordova.getActivity().runOnUiThread(() -> {
+            mPromptInfoBuilder.parseArgs(args);
+            Intent intent = new Intent(cordova.getActivity().getApplicationContext(), BiometricActivity.class);
+            intent.putExtras(mPromptInfoBuilder.build().getBundle());
+            this.cordova.startActivityForResult(this, intent, REQUEST_CODE_BIOMETRIC);
+        });
+        PluginResult pluginResult = new PluginResult(PluginResult.Status.NO_RESULT);
+        pluginResult.setKeepCallback(true);
+        this.mCallbackContext.sendPluginResult(pluginResult);
     }
 
-    private static SecretKey getSecretKey() {
-        String errorMessage = "";
-        String getSecretKeyExceptionErrorPrefix = "Failed to get SecretKey from KeyStore: ";
-        SecretKey key = null;
-        try {
-            mKeyStore.load(null);
-            key = (SecretKey) mKeyStore.getKey(mClientId, null);
-        } catch (KeyStoreException e) {
-            errorMessage = getSecretKeyExceptionErrorPrefix
-                    + "KeyStoreException: " + e.toString();;
-        } catch (CertificateException e) {
-            errorMessage = getSecretKeyExceptionErrorPrefix
-                    + "CertificateException: " + e.toString();;
-        } catch (UnrecoverableKeyException e) {
-            errorMessage = getSecretKeyExceptionErrorPrefix
-                    + "UnrecoverableKeyException: " + e.toString();;
-        } catch (IOException e) {
-            errorMessage = getSecretKeyExceptionErrorPrefix
-                    + "IOException: " + e.toString();;
-        } catch (NoSuchAlgorithmException e) {
-            errorMessage = getSecretKeyExceptionErrorPrefix
-                    + "NoSuchAlgorithmException: " + e.toString();;
+    @Override
+    public void onActivityResult(int requestCode, int resultCode, Intent intent) {
+        super.onActivityResult(requestCode, resultCode, intent);
+        if (requestCode != REQUEST_CODE_BIOMETRIC) {
+            return;
         }
-        if (key == null) {
-            Log.e(TAG, errorMessage);
+        if (resultCode == Activity.RESULT_OK) {
+            sendSuccess("biometric_success");
+        } else if (intent != null) {
+            Bundle extras = intent.getExtras();
+            sendError(extras.getInt("code"), extras.getString("message"));
+        } else {
+            sendError(PluginError.BIOMETRIC_DISMISSED);
         }
-        return key;
     }
 
-    /**
-     * Creates a symmetric key in the Android Key Store which can only be used after the user has
-     * authenticated with fingerprint.
-     */
-    public static boolean createKey() {
-        String errorMessage = "";
-        String createKeyExceptionErrorPrefix = "Failed to create key: ";
-        boolean isKeyCreated = false;
-        // The enrolling flow for fingerprint. This is where you ask the user to set up fingerprint
-        // for your flow. Use of keys is necessary if you need to know if the set of
-        // enrolled fingerprints has changed.
-        try {
-            mKeyStore.load(null);
-            // Set the alias of the entry in Android KeyStore where the key will appear
-            // and the constrains (purposes) in the constructor of the Builder
-            mKeyGenerator.init(new KeyGenParameterSpec.Builder(mClientId,
-                    KeyProperties.PURPOSE_ENCRYPT |
-                            KeyProperties.PURPOSE_DECRYPT)
-                    .setBlockModes(KeyProperties.BLOCK_MODE_CBC)
-                            // Require the user to authenticate with a fingerprint to authorize every use
-                            // of the key
-                    .setUserAuthenticationRequired(true)
-                    .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_PKCS7)
-                    .build());
-            mKeyGenerator.generateKey();
-            isKeyCreated = true;
-        } catch (NoSuchAlgorithmException e) {
-            errorMessage = createKeyExceptionErrorPrefix
-                    + "NoSuchAlgorithmException: " + e.toString();;
-        } catch (InvalidAlgorithmParameterException e) {
-            errorMessage = createKeyExceptionErrorPrefix
-                    + "InvalidAlgorithmParameterException: " + e.toString();;
-        } catch (CertificateException e) {
-            errorMessage = createKeyExceptionErrorPrefix
-                    + "CertificateException: " + e.toString();;
-        } catch (IOException e) {
-            errorMessage = createKeyExceptionErrorPrefix
-                    + "IOException: " + e.toString();;
-        }
-        if (!isKeyCreated) {
-            Log.e(TAG, errorMessage);
-            setPluginResultError(errorMessage);
+    private PluginError canAuthenticate() {
+        int error = BiometricManager.from(cordova.getContext()).canAuthenticate();
+        switch (error) {
+            case BiometricManager.BIOMETRIC_ERROR_HW_UNAVAILABLE:
+            case BiometricManager.BIOMETRIC_ERROR_NO_HARDWARE:
+                return PluginError.BIOMETRIC_HARDWARE_NOT_SUPPORTED;
+            case BiometricManager.BIOMETRIC_ERROR_NONE_ENROLLED:
+                return PluginError.BIOMETRIC_NOT_ENROLLED;
+            default:
+                return null;
         }
-        return isKeyCreated;
     }
 
-    public static void onAuthenticated(boolean withFingerprint) {
+    private void sendError(int code, String message) {
         JSONObject resultJson = new JSONObject();
-        String errorMessage = "";
-        boolean createdResultJson = false;
         try {
+            resultJson.put("code", code);
+            resultJson.put("message", message);
 
-            if (withFingerprint) {
-                // If the user has authenticated with fingerprint, verify that using cryptography and
-                // then return the encrypted token
-                byte[] encrypted = tryEncrypt();
-                resultJson.put("withFingerprint", Base64.encodeToString(encrypted, 0 /* flags */));
-            } else {
-                // Authentication happened with backup password.
-                resultJson.put("withPassword", true);
-
-                // if failed to init cipher because of InvalidKeyException, create new key
-                if (!initCipher()) {
-                    createKey();
-                }
-            }
-            createdResultJson = true;
-        } catch (BadPaddingException e) {
-            errorMessage = "Failed to encrypt the data with the generated key:" +
-                    " BadPaddingException:  " + e.getMessage();
-            Log.e(TAG, errorMessage);
-        } catch (IllegalBlockSizeException e) {
-            errorMessage = "Failed to encrypt the data with the generated key: " +
-                    "IllegalBlockSizeException: " + e.getMessage();
-            Log.e(TAG, errorMessage);
+            PluginResult result = new PluginResult(PluginResult.Status.ERROR, resultJson);
+            result.setKeepCallback(true);
+            cordova.getActivity().runOnUiThread(() ->
+                    Fingerprint.this.mCallbackContext.sendPluginResult(result));
         } catch (JSONException e) {
-            errorMessage = "Failed to set resultJson key value pair: " + e.getMessage();
-            Log.e(TAG, errorMessage);
-        }
-
-        if (createdResultJson) {
-            mCallbackContext.success(resultJson);
-            mPluginResult = new PluginResult(PluginResult.Status.OK);
-        } else {
-            mCallbackContext.error(errorMessage);
-            mPluginResult = new PluginResult(PluginResult.Status.ERROR);
+            Log.e(TAG, e.getMessage(), e);
         }
-        mCallbackContext.sendPluginResult(mPluginResult);
     }
 
-    public static void onCancelled() {
-        mCallbackContext.error("Cancelled");
+    private void sendError(PluginError error) {
+        sendError(error.getValue(), error.getMessage());
     }
 
-    /**
-     * Tries to encrypt some data with the generated key in {@link #createKey} which is
-     * only works if the user has just authenticated via fingerprint.
-     */
-    private static byte[] tryEncrypt() throws BadPaddingException, IllegalBlockSizeException {
-        return mCipher.doFinal(mClientSecret.getBytes());
-    }
-
-    public static boolean setPluginResultError(String errorMessage) {
-        mCallbackContext.error(errorMessage);
-        mPluginResult = new PluginResult(PluginResult.Status.ERROR);
-        return false;
+    private void sendSuccess(String message) {
+        Log.e(TAG, message);
+        cordova.getActivity().runOnUiThread(() ->
+                this.mCallbackContext.success(message));
     }
-}
\ No newline at end of file
+}
diff --git a/plugins/cordova-plugin-fingerprint-aio/src/android/FingerprintAuthenticationDialogFragment.java b/plugins/cordova-plugin-fingerprint-aio/src/android/FingerprintAuthenticationDialogFragment.java
deleted file mode 100644 (file)
index 54fb28d..0000000
+++ /dev/null
@@ -1,268 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- * Modifications copyright (C) 2016 Niklas Merz
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package de.niklasmerz.cordova.fingerprint;
-
-import android.app.DialogFragment;
-import android.app.KeyguardManager;
-import android.content.Context;
-import android.content.DialogInterface;
-import android.content.Intent;
-import android.content.SharedPreferences;
-import android.hardware.fingerprint.FingerprintManager;
-import android.os.Bundle;
-import android.util.Log;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.view.inputmethod.InputMethodManager;
-import android.widget.Button;
-import android.widget.ImageView;
-import android.widget.TextView;
-import android.widget.Toast;
-
-/**
- * A dialog which uses fingerprint APIs to authenticate the user, and falls back to password
- * authentication if fingerprint is not available.
- */
-public class FingerprintAuthenticationDialogFragment extends DialogFragment
-        implements FingerprintUiHelper.Callback {
-
-    private static final String TAG = "FingerprintAuthDialog";
-    private static final int REQUEST_CODE_CONFIRM_DEVICE_CREDENTIALS = 1;
-
-    private Button mCancelButton;
-    private Button mSecondDialogButton;
-    private View mFingerprintContent;
-
-    private Stage mStage = Stage.FINGERPRINT;
-
-    private KeyguardManager mKeyguardManager;
-    private FingerprintManager.CryptoObject mCryptoObject;
-    private FingerprintUiHelper mFingerprintUiHelper;
-    FingerprintUiHelper.FingerprintUiHelperBuilder mFingerprintUiHelperBuilder;
-
-    boolean disableBackup;
-
-    public FingerprintAuthenticationDialogFragment() {
-    }
-
-    @Override
-    public void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-
-        // Do not create a new Fragment when the Activity is re-created such as orientation changes.
-        setRetainInstance(true);
-        setStyle(DialogFragment.STYLE_NORMAL, android.R.style.Theme_Material_Light_Dialog);
-
-        mKeyguardManager = (KeyguardManager) getContext().getSystemService(Context.KEYGUARD_SERVICE);
-        mFingerprintUiHelperBuilder = new FingerprintUiHelper.FingerprintUiHelperBuilder(
-                getContext(), getContext().getSystemService(FingerprintManager.class));
-
-    }
-
-    @Override
-    public View onCreateView(LayoutInflater inflater, ViewGroup container,
-                             Bundle savedInstanceState) {
-        Bundle args = getArguments();
-        disableBackup = args.getBoolean("disableBackup");
-        Log.d(TAG, "disableBackup: " + disableBackup);
-
-        int fingerprint_auth_dialog_title_id = getResources()
-                .getIdentifier("fingerprint_auth_dialog_title", "string",
-                        Fingerprint.packageName);
-        getDialog().setTitle(getString(fingerprint_auth_dialog_title_id));
-        int fingerprint_dialog_container_id = getResources()
-                .getIdentifier("fingerprint_dialog_container", "layout",
-                        Fingerprint.packageName);
-        View v = inflater.inflate(fingerprint_dialog_container_id, container, false);
-        int cancel_button_id = getResources()
-                .getIdentifier("cancel_button", "id", Fingerprint.packageName);
-        mCancelButton = (Button) v.findViewById(cancel_button_id);
-        mCancelButton.setOnClickListener(new View.OnClickListener() {
-            @Override
-            public void onClick(View view) {
-                Fingerprint.onCancelled();
-                dismissAllowingStateLoss();
-            }
-        });
-
-        int second_dialog_button_id = getResources()
-                .getIdentifier("second_dialog_button", "id", Fingerprint.packageName);
-        mSecondDialogButton = (Button) v.findViewById(second_dialog_button_id);
-        if (disableBackup) {
-            mSecondDialogButton.setVisibility(View.GONE);
-        }
-        mSecondDialogButton.setOnClickListener(new View.OnClickListener() {
-            @Override
-            public void onClick(View view) {
-                goToBackup();
-            }
-        });
-        int fingerprint_container_id = getResources()
-                .getIdentifier("fingerprint_container", "id", Fingerprint.packageName);
-        mFingerprintContent = v.findViewById(fingerprint_container_id);
-
-        int new_fingerprint_enrolled_description_id = getResources()
-                .getIdentifier("new_fingerprint_enrolled_description", "id",
-                        Fingerprint.packageName);
-
-        int fingerprint_icon_id = getResources()
-                .getIdentifier("fingerprint_icon", "id", Fingerprint.packageName);
-        int fingerprint_status_id = getResources()
-                .getIdentifier("fingerprint_status", "id", Fingerprint.packageName);
-        mFingerprintUiHelper = mFingerprintUiHelperBuilder.build(
-                (ImageView) v.findViewById(fingerprint_icon_id),
-                (TextView) v.findViewById(fingerprint_status_id), this);
-        updateStage();
-
-        // If fingerprint authentication is not available, switch immediately to the backup
-        // (password) screen.
-        if (!mFingerprintUiHelper.isFingerprintAuthAvailable()) {
-            goToBackup();
-        }
-        return v;
-    }
-
-
-    @Override
-    public void onResume() {
-        super.onResume();
-        if (mStage == Stage.FINGERPRINT) {
-            mFingerprintUiHelper.startListening(mCryptoObject);
-        }
-    }
-
-    public void setStage(Stage stage) {
-        mStage = stage;
-    }
-
-    @Override
-    public void onPause() {
-        super.onPause();
-        mFingerprintUiHelper.stopListening();
-    }
-
-    /**
-     * Sets the crypto object to be passed in when authenticating with fingerprint.
-     */
-    public void setCryptoObject(FingerprintManager.CryptoObject cryptoObject) {
-        mCryptoObject = cryptoObject;
-    }
-
-    /**
-     * Switches to backup (password) screen. This either can happen when fingerprint is not
-     * available or the user chooses to use the password authentication method by pressing the
-     * button. This can also happen when the user had too many fingerprint attempts.
-     */
-    private void goToBackup() {
-        if(disableBackup)
-        {
-            Fingerprint.onCancelled(); 
-            dismissAllowingStateLoss();
-        }
-        else{
-            mStage = Stage.BACKUP;
-            updateStage();
-        }
-    }
-
-    private void updateStage() {
-        int cancel_id = getResources()
-                .getIdentifier("fingerprint_cancel", "string", Fingerprint.packageName);
-        switch (mStage) {
-            case FINGERPRINT:
-                mCancelButton.setText(cancel_id);
-                int use_backup_id = getResources()
-                        .getIdentifier("fingerprint_use_backup", "string", Fingerprint.packageName);
-                mSecondDialogButton.setText(use_backup_id);
-                mFingerprintContent.setVisibility(View.VISIBLE);
-                break;
-            case NEW_FINGERPRINT_ENROLLED:
-                // Intentional fall through
-            case BACKUP:
-                if (mStage == Stage.NEW_FINGERPRINT_ENROLLED) {
-
-                }
-                if (!mKeyguardManager.isKeyguardSecure()) {
-                    // Show a message that the user hasn't set up a lock screen.
-                    int secure_lock_screen_required_id = getResources()
-                            .getIdentifier("secure_lock_screen_required", "string",
-                                    Fingerprint.packageName);
-                    Toast.makeText(getContext(),
-                            getString(secure_lock_screen_required_id),
-                            Toast.LENGTH_LONG).show();
-                    return;
-                }
-                showAuthenticationScreen();
-                break;
-        }
-    }
-
-    private void showAuthenticationScreen() {
-        // Create the Confirm Credentials screen. You can customize the title and description. Or
-        // we will provide a generic one for you if you leave it null
-        Intent intent = mKeyguardManager.createConfirmDeviceCredentialIntent(null, null);
-        if (intent != null) {
-            startActivityForResult(intent, REQUEST_CODE_CONFIRM_DEVICE_CREDENTIALS);
-        }
-    }
-
-    @Override
-    public void onActivityResult(int requestCode, int resultCode, Intent data) {
-        if (requestCode == REQUEST_CODE_CONFIRM_DEVICE_CREDENTIALS) {
-            // Challenge completed, proceed with using cipher
-            if (resultCode == getActivity().RESULT_OK) {
-                Fingerprint.onAuthenticated(false /* used backup */);
-            } else {
-                // The user canceled or didn’t complete the lock screen
-                // operation. Go to error/cancellation flow.
-                Fingerprint.onCancelled();
-            }
-            dismissAllowingStateLoss();
-        }
-    }
-
-    @Override
-    public void onAuthenticated() {
-        // Callback from FingerprintUiHelper. Let the activity know that authentication was
-        // successful.
-        Fingerprint.onAuthenticated(true /* withFingerprint */);
-        dismissAllowingStateLoss();
-    }
-
-    @Override
-    public void onError() {
-        if(this.getActivity() != null)
-            goToBackup();
-    }
-
-    @Override
-    public void onCancel(DialogInterface dialog) {
-        super.onCancel(dialog);
-        Fingerprint.onCancelled();
-    }
-
-    /**
-     * Enumeration to indicate which authentication method the user is trying to authenticate with.
-     */
-    public enum Stage {
-        FINGERPRINT,
-        NEW_FINGERPRINT_ENROLLED,
-        BACKUP
-    }
-}
diff --git a/plugins/cordova-plugin-fingerprint-aio/src/android/FingerprintUiHelper.java b/plugins/cordova-plugin-fingerprint-aio/src/android/FingerprintUiHelper.java
deleted file mode 100644 (file)
index e1402c5..0000000
+++ /dev/null
@@ -1,189 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- * Modifications copyright (C) 2016 Niklas Merz
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package de.niklasmerz.cordova.fingerprint;
-
-import android.annotation.TargetApi;
-import android.content.Context;
-import android.hardware.fingerprint.FingerprintManager;
-import android.os.CancellationSignal;
-import android.widget.ImageView;
-import android.widget.TextView;
-
-
-/**
- * Small helper class to manage text/icon around fingerprint authentication UI.
- */
-@TargetApi(23)
-public class FingerprintUiHelper extends FingerprintManager.AuthenticationCallback {
-
-    static final long ERROR_TIMEOUT_MILLIS = 1600;
-    static final long SUCCESS_DELAY_MILLIS = 1300;
-
-    private final Context mContext;
-    private final FingerprintManager mFingerprintManager;
-    private final ImageView mIcon;
-    private final TextView mErrorTextView;
-    private final Callback mCallback;
-    private CancellationSignal mCancellationSignal;
-
-    boolean mSelfCancelled;
-
-    /**
-     * Builder class for {@link FingerprintUiHelper} in which injected fields from Dagger
-     * holds its fields and takes other arguments in the {@link #build} method.
-     */
-    public static class FingerprintUiHelperBuilder {
-        private final FingerprintManager mFingerPrintManager;
-        private final Context mContext;
-
-        public FingerprintUiHelperBuilder(Context context, FingerprintManager fingerprintManager) {
-            mFingerPrintManager = fingerprintManager;
-            mContext = context;
-        }
-
-        public FingerprintUiHelper build(ImageView icon, TextView errorTextView, Callback callback) {
-            return new FingerprintUiHelper(mContext, mFingerPrintManager, icon, errorTextView,
-                    callback);
-        }
-    }
-
-    /**
-     * Constructor for {@link FingerprintUiHelper}. This method is expected to be called from
-     * only the {@link FingerprintUiHelperBuilder} class.
-     */
-    private FingerprintUiHelper(Context context, FingerprintManager fingerprintManager,
-            ImageView icon, TextView errorTextView, Callback callback) {
-        mFingerprintManager = fingerprintManager;
-        mIcon = icon;
-        mErrorTextView = errorTextView;
-        mCallback = callback;
-        mContext = context;
-    }
-
-    public boolean isFingerprintAuthAvailable() {
-        return mFingerprintManager.isHardwareDetected()
-                && mFingerprintManager.hasEnrolledFingerprints();
-    }
-
-    public void startListening(FingerprintManager.CryptoObject cryptoObject) {
-        if (!isFingerprintAuthAvailable()) {
-            return;
-        }
-        mCancellationSignal = new CancellationSignal();
-        mSelfCancelled = false;
-        mFingerprintManager
-                .authenticate(cryptoObject, mCancellationSignal, 0 /* flags */, this, null);
-
-        int ic_fp_40px_id = mContext.getResources()
-                .getIdentifier("ic_fp_40px", "drawable", Fingerprint.packageName);
-        mIcon.setImageResource(ic_fp_40px_id);
-    }
-
-    public void stopListening() {
-        if (mCancellationSignal != null) {
-            mSelfCancelled = true;
-            mCancellationSignal.cancel();
-            mCancellationSignal = null;
-        }
-    }
-
-    @Override
-    public void onAuthenticationError(int errMsgId, CharSequence errString) {
-        if (!mSelfCancelled) {
-            showError(errString);
-            mIcon.postDelayed(new Runnable() {
-                @Override
-                public void run() {
-                    mCallback.onError();
-                }
-            }, ERROR_TIMEOUT_MILLIS);
-        }
-    }
-
-    @Override
-    public void onAuthenticationHelp(int helpMsgId, CharSequence helpString) {
-        showError(helpString);
-    }
-
-    @Override
-    public void onAuthenticationFailed() {
-        int fingerprint_not_recognized_id = mContext.getResources()
-                .getIdentifier("fingerprint_not_recognized", "string", Fingerprint.packageName);
-        showError(mIcon.getResources().getString(
-                fingerprint_not_recognized_id));
-    }
-
-    @Override
-    public void onAuthenticationSucceeded(FingerprintManager.AuthenticationResult result) {
-        mErrorTextView.removeCallbacks(mResetErrorTextRunnable);
-        int ic_fingerprint_success_id = mContext.getResources()
-                .getIdentifier("ic_fingerprint_success", "drawable", Fingerprint.packageName);
-        mIcon.setImageResource(ic_fingerprint_success_id);
-        int success_color_id = mContext.getResources()
-                .getIdentifier("success_color", "color", Fingerprint.packageName);
-        mErrorTextView.setTextColor(
-                mErrorTextView.getResources().getColor(success_color_id, null));
-        int fingerprint_success_id = mContext.getResources()
-                .getIdentifier("fingerprint_success", "string", Fingerprint.packageName);
-        mErrorTextView.setText(
-                mErrorTextView.getResources().getString(fingerprint_success_id));
-        mIcon.postDelayed(new Runnable() {
-            @Override
-            public void run() {
-                mCallback.onAuthenticated();
-            }
-        }, SUCCESS_DELAY_MILLIS);
-    }
-
-    private void showError(CharSequence error) {
-        int ic_fingerprint_error_id = mContext.getResources()
-                .getIdentifier("ic_fingerprint_error", "drawable", Fingerprint.packageName);
-        mIcon.setImageResource(ic_fingerprint_error_id);
-        mErrorTextView.setText(error);
-        int warning_color_id = mContext.getResources()
-                .getIdentifier("warning_color", "color", Fingerprint.packageName);
-        mErrorTextView.setTextColor(
-                mErrorTextView.getResources().getColor(warning_color_id, null));
-        mErrorTextView.removeCallbacks(mResetErrorTextRunnable);
-        mErrorTextView.postDelayed(mResetErrorTextRunnable, ERROR_TIMEOUT_MILLIS);
-    }
-
-    Runnable mResetErrorTextRunnable = new Runnable() {
-        @Override
-        public void run() {
-            int hint_color_id = mContext.getResources()
-                    .getIdentifier("hint_color", "color", Fingerprint.packageName);
-            mErrorTextView.setTextColor(
-                    mErrorTextView.getResources().getColor(hint_color_id, null));
-            int fingerprint_hint_id = mContext.getResources()
-                    .getIdentifier("fingerprint_hint", "string", Fingerprint.packageName);
-            mErrorTextView.setText(
-                    mErrorTextView.getResources().getString(fingerprint_hint_id));
-            int ic_fp_40px_id = mContext.getResources()
-                    .getIdentifier("ic_fp_40px", "drawable", Fingerprint.packageName);
-            mIcon.setImageResource(ic_fp_40px_id);
-        }
-    };
-
-    public interface Callback {
-
-        void onAuthenticated();
-
-        void onError();
-    }
-}
diff --git a/plugins/cordova-plugin-fingerprint-aio/src/android/PluginError.java b/plugins/cordova-plugin-fingerprint-aio/src/android/PluginError.java
new file mode 100644 (file)
index 0000000..1a4a5db
--- /dev/null
@@ -0,0 +1,35 @@
+package de.niklasmerz.cordova.biometric;
+
+public enum PluginError {
+
+    BIOMETRIC_AUTHENTICATION_FAILED(-102, "Authentication failed"),
+    BIOMETRIC_HARDWARE_NOT_SUPPORTED(-104),
+    BIOMETRIC_NOT_ENROLLED(-106),
+    BIOMETRIC_DISMISSED(-108),
+    BIOMETRIC_PIN_OR_PATTERN_DISMISSED(-109),
+    BIOMETRIC_SCREEN_GUARD_UNSECURED(-110,
+            "Go to 'Settings -> Security -> Screenlock' to set up a lock screen"),
+    BIOMETRIC_LOCKED_OUT(-111),
+    BIOMETRIC_LOCKED_OUT_PERMANENT(-112);
+
+    private int value;
+    private String message;
+
+    PluginError(int value) {
+        this.value = value;
+        this.message = this.name();
+    }
+
+    PluginError(int value, String message) {
+        this.value = value;
+        this.message = message;
+    }
+
+    public int getValue() {
+        return value;
+    }
+
+    public String getMessage() {
+        return message;
+    }
+}
diff --git a/plugins/cordova-plugin-fingerprint-aio/src/android/PromptInfo.java b/plugins/cordova-plugin-fingerprint-aio/src/android/PromptInfo.java
new file mode 100644 (file)
index 0000000..31ed0dd
--- /dev/null
@@ -0,0 +1,136 @@
+package de.niklasmerz.cordova.biometric;
+
+import android.content.Context;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
+import android.os.Bundle;
+import android.util.Log;
+
+import org.json.JSONArray;
+import org.json.JSONException;
+import org.json.JSONObject;
+
+class PromptInfo {
+
+    private static final String DISABLE_BACKUP = "disableBackup";
+    private static final String TITLE = "title";
+    private static final String SUBTITLE = "subtitle";
+    private static final String DESCRIPTION = "description";
+    private static final String FALLBACK_BUTTON_TITLE = "fallbackButtonTitle";
+    private static final String CANCEL_BUTTON_TITLE = "cancelButtonTitle";
+
+    private Bundle bundle = new Bundle();
+
+    Bundle getBundle() {
+        return bundle;
+    }
+
+    String getTitle() {
+        return bundle.getString(TITLE);
+    }
+
+    String getSubtitle() {
+        return bundle.getString(SUBTITLE);
+    }
+
+    String getDescription() {
+        return bundle.getString(DESCRIPTION);
+    }
+
+    boolean isDeviceCredentialAllowed() {
+        return !bundle.getBoolean(DISABLE_BACKUP);
+    }
+
+    String getFallbackButtonTitle() {
+        return bundle.getString(FALLBACK_BUTTON_TITLE);
+    }
+
+    String getCancelButtonTitle() {
+        return bundle.getString(CANCEL_BUTTON_TITLE);
+    }
+
+    public static final class Builder {
+        private static final String TAG = "PromptInfo.Builder";
+        private Bundle bundle;
+        private boolean disableBackup = false;
+        private String title;
+        private String subtitle = null;
+        private String description = null;
+        private String fallbackButtonTitle = "Use backup";
+        private String cancelButtonTitle = "Cancel";
+
+        Builder(Context context) {
+            PackageManager packageManager = context.getPackageManager();
+            try {
+                ApplicationInfo app = packageManager
+                        .getApplicationInfo(context.getPackageName(), 0);
+                title = packageManager.getApplicationLabel(app) + " Biometric Sign On";
+            } catch (PackageManager.NameNotFoundException e) {
+                title = "Biometric Sign On";
+            }
+        }
+
+        Builder(Bundle bundle) {
+            this.bundle = bundle;
+        }
+
+        public PromptInfo build() {
+            PromptInfo promptInfo = new PromptInfo();
+
+            if (this.bundle != null) {
+                promptInfo.bundle = bundle;
+                return promptInfo;
+            }
+
+            Bundle bundle = new Bundle();
+            bundle.putString(SUBTITLE, this.subtitle);
+            bundle.putString(TITLE, this.title);
+            bundle.putString(DESCRIPTION, this.description);
+            bundle.putString(FALLBACK_BUTTON_TITLE, this.fallbackButtonTitle);
+            bundle.putString(CANCEL_BUTTON_TITLE, this.cancelButtonTitle);
+            bundle.putBoolean(DISABLE_BACKUP, this.disableBackup);
+            promptInfo.bundle = bundle;
+
+            return promptInfo;
+        }
+
+        void parseArgs(JSONArray args) {
+            JSONObject argsObject;
+            try {
+                argsObject = args.getJSONObject(0);
+            } catch (JSONException e) {
+                Log.e(TAG, "Can't parse args. Defaults will be used.", e);
+                return;
+            }
+            disableBackup = getBooleanArg(argsObject, DISABLE_BACKUP, disableBackup);
+            title = getStringArg(argsObject, TITLE, title);
+            subtitle = getStringArg(argsObject, SUBTITLE, subtitle);
+            description = getStringArg(argsObject, DESCRIPTION, description);
+            fallbackButtonTitle = getStringArg(argsObject, FALLBACK_BUTTON_TITLE, "Use Backup");
+            cancelButtonTitle = getStringArg(argsObject, CANCEL_BUTTON_TITLE, "Cancel");
+        }
+
+        private Boolean getBooleanArg(JSONObject argsObject, String name, Boolean defaultValue) {
+            if (argsObject.has(name)){
+                try {
+                    return argsObject.getBoolean(name);
+                } catch (JSONException e) {
+                    Log.e(TAG, "Can't parse '" + name + "'. Default will be used.", e);
+                }
+            }
+            return defaultValue;
+        }
+
+        private String getStringArg(JSONObject argsObject, String name, String defaultValue) {
+            if (argsObject.optString(name) != null
+                    && !argsObject.optString(name).isEmpty()){
+                try {
+                    return argsObject.getString(name);
+                } catch (JSONException e) {
+                    Log.e(TAG, "Can't parse '" + name + "'. Default will be used.", e);
+                }
+            }
+            return defaultValue;
+        }
+    }
+}
diff --git a/plugins/cordova-plugin-fingerprint-aio/src/android/build.gradle b/plugins/cordova-plugin-fingerprint-aio/src/android/build.gradle
new file mode 100644 (file)
index 0000000..aad4f13
--- /dev/null
@@ -0,0 +1,30 @@
+allprojects {
+    repositories {
+        maven { url 'https://jitpack.io' }
+    }
+}
+
+dependencies {
+
+    /**
+     * The android-biometric.aar file has been taken from com.github.exxbrain:android-biometric library.
+     * Android biometric library is a clone of androidx.biometric library adapted for non-androidx apps.
+     * This project could be found at https://github.com/exxbrain/android-biometric.
+     * It has Apache License 2.0.
+     *
+     * TODO: Temporary solution. Should be removed after moving cordova-android to androidx. Then use androidx.biometric.
+     */
+    implementation 'com.github.exxbrain:android-biometric:0.4'
+
+    implementation 'com.android.support:design:28.0.0'
+    implementation 'com.android.support:appcompat-v7:28.0.0'
+    implementation 'com.android.support:support-v4:28.0.0'
+    implementation 'com.android.support:support-annotations:28.0.0'
+}
+
+android {
+    packagingOptions {
+        exclude 'META-INF/NOTICE'
+        exclude 'META-INF/LICENSE'
+    }
+}
diff --git a/plugins/cordova-plugin-fingerprint-aio/src/android/res/biometric_activity.xml b/plugins/cordova-plugin-fingerprint-aio/src/android/res/biometric_activity.xml
new file mode 100644 (file)
index 0000000..5708761
--- /dev/null
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  Copyright 2019 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent" android:layout_height="match_parent">
+
+</FrameLayout>
\ No newline at end of file
diff --git a/plugins/cordova-plugin-fingerprint-aio/src/android/res/styles.xml b/plugins/cordova-plugin-fingerprint-aio/src/android/res/styles.xml
new file mode 100644 (file)
index 0000000..06d9cbb
--- /dev/null
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  Copyright 2019 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+
+<resources>
+    <style name="TransparentTheme" parent="Theme.AppCompat">
+        <item name="android:windowIsTranslucent">true</item>
+        <item name="android:windowBackground">@android:color/transparent</item>
+        <item name="android:windowContentOverlay">@null</item>
+        <item name="android:windowNoTitle">true</item>
+        <item name="android:windowIsFloating">true</item>
+        <item name="android:backgroundDimEnabled">false</item>
+    </style>
+</resources>
\ No newline at end of file
index 547aeb2..1f01be4 100644 (file)
@@ -1,23 +1,47 @@
 import Foundation
 import LocalAuthentication
 
+
 @objc(Fingerprint) class Fingerprint : CDVPlugin {
 
+    enum PluginError:Int {
+        case BIOMETRIC_UNKNOWN_ERROR = -100
+        case BIOMETRIC_UNAVAILABLE = -101
+        case BIOMETRIC_AUTHENTICATION_FAILED = -102
+        case BIOMETRIC_PERMISSION_NOT_GRANTED = -105
+        case BIOMETRIC_NOT_ENROLLED = -106
+        case BIOMETRIC_DISMISSED = -108
+        case BIOMETRIC_SCREEN_GUARD_UNSECURED = -110
+        case BIOMETRIC_LOCKED_OUT = -111
+    }
+
+    struct ErrorCodes {
+        var code: Int
+    }
+
+
     @objc(isAvailable:)
     func isAvailable(_ command: CDVInvokedUrlCommand){
         let authenticationContext = LAContext();
         var biometryType = "finger";
+        var errorResponse: [AnyHashable: Any] = [
+            "code": 0,
+            "message": "Not Available"
+        ];
         var error:NSError?;
         let policy:LAPolicy = .deviceOwnerAuthenticationWithBiometrics;
-
+        var pluginResult = CDVPluginResult(status: CDVCommandStatus_ERROR, messageAs: "Not available");
         let available = authenticationContext.canEvaluatePolicy(policy, error: &error);
 
+        var results: [String : Any]
+
         if(error != nil){
             biometryType = "none";
+            errorResponse["code"] = error?.code;
+            errorResponse["message"] = error?.localizedDescription;
         }
 
-        var pluginResult = CDVPluginResult(status: CDVCommandStatus_ERROR, messageAs: "Not available");
-        if available == true {
+        if (available == true) {
             if #available(iOS 11.0, *) {
                 switch(authenticationContext.biometryType) {
                 case .none:
@@ -30,6 +54,22 @@ import LocalAuthentication
             }
 
             pluginResult = CDVPluginResult(status: CDVCommandStatus_OK, messageAs: biometryType);
+        }else{
+            var code: Int;
+            switch(error!._code) {
+                case Int(kLAErrorBiometryNotAvailable):
+                    code = PluginError.BIOMETRIC_UNAVAILABLE.rawValue;
+                    break;
+                case Int(kLAErrorBiometryNotEnrolled):
+                    code = PluginError.BIOMETRIC_NOT_ENROLLED.rawValue;
+                    break;
+
+                default:
+                    code = PluginError.BIOMETRIC_UNKNOWN_ERROR.rawValue;
+                    break;
+            }
+            results = ["code": code, "message": error!.localizedDescription];
+            pluginResult = CDVPluginResult(status: CDVCommandStatus_ERROR, messageAs: results);
         }
 
         commandDelegate.send(pluginResult, callbackId:command.callbackId);
@@ -39,7 +79,10 @@ import LocalAuthentication
     @objc(authenticate:)
     func authenticate(_ command: CDVInvokedUrlCommand){
         let authenticationContext = LAContext();
-        var pluginResult = CDVPluginResult(status: CDVCommandStatus_ERROR, messageAs: "Something went wrong");
+        var errorResponse: [AnyHashable: Any] = [
+            "message": "Something went wrong"
+        ];
+        var pluginResult = CDVPluginResult(status: CDVCommandStatus_ERROR, messageAs: errorResponse);
         var reason = "Authentication";
         var policy:LAPolicy = .deviceOwnerAuthentication;
         let data  = command.arguments[0] as AnyObject?;
@@ -49,17 +92,17 @@ import LocalAuthentication
                 authenticationContext.localizedFallbackTitle = "";
                 policy = .deviceOwnerAuthenticationWithBiometrics;
             } else {
-                if let localizedFallbackTitle = data?["localizedFallbackTitle"] as! String? {
-                    authenticationContext.localizedFallbackTitle = localizedFallbackTitle;
+                if let fallbackButtonTitle = data?["fallbackButtonTitle"] as! String? {
+                    authenticationContext.localizedFallbackTitle = fallbackButtonTitle;
+                }else{
+                    authenticationContext.localizedFallbackTitle = "Use Pin";
                 }
             }
         }
 
         // Localized reason
-        if let localizedReason = data?["localizedReason"] as! String? {
-            reason = localizedReason;
-        }else if let clientId = data?["clientId"] as! String? {
-            reason = clientId;
+        if let description = data?["description"] as! String? {
+            reason = description;
         }
 
         authenticationContext.evaluatePolicy(
@@ -69,17 +112,32 @@ import LocalAuthentication
                 if( success ) {
                     pluginResult = CDVPluginResult(status: CDVCommandStatus_OK, messageAs: "Success");
                 }else {
-                    // Check if there is an error
-                    if error != nil {
-                        pluginResult = CDVPluginResult(status: CDVCommandStatus_ERROR, messageAs: "Error: \(String(describing: error?.localizedDescription))")
+                    if (error != nil) {
+
+                        var errorCodes = [Int: ErrorCodes]()
+                        var errorResult: [String : Any] = ["code":  PluginError.BIOMETRIC_UNKNOWN_ERROR.rawValue, "message": error?.localizedDescription ?? ""];
+
+                        errorCodes[1] = ErrorCodes(code: PluginError.BIOMETRIC_AUTHENTICATION_FAILED.rawValue)
+                        errorCodes[2] = ErrorCodes(code: PluginError.BIOMETRIC_DISMISSED.rawValue)
+                        errorCodes[5] = ErrorCodes(code: PluginError.BIOMETRIC_SCREEN_GUARD_UNSECURED.rawValue)
+                        errorCodes[6] = ErrorCodes(code: PluginError.BIOMETRIC_UNAVAILABLE.rawValue)
+                        errorCodes[7] = ErrorCodes(code: PluginError.BIOMETRIC_NOT_ENROLLED.rawValue)
+                        errorCodes[8] = ErrorCodes(code: PluginError.BIOMETRIC_LOCKED_OUT.rawValue)
+
+                        let errorCode = abs(error!._code)
+                        if let e = errorCodes[errorCode] {
+                           errorResult = ["code": e.code, "message": error!.localizedDescription];
+                        }
+
+                        pluginResult = CDVPluginResult(status: CDVCommandStatus_ERROR, messageAs: errorResult);
                     }
                 }
                 self.commandDelegate.send(pluginResult, callbackId:command.callbackId);
-        });
+            }
+        );
     }
 
     override func pluginInitialize() {
         super.pluginInitialize()
     }
-}
-
+}
\ No newline at end of file
index 7332656..e01debe 100644 (file)
@@ -1,7 +1,27 @@
 /*global cordova */
 
-function Fingerprint() {
-}
+var Fingerprint = function() {
+};
+
+// Plugin Errors
+Fingerprint.prototype.BIOMETRIC_UNKNOWN_ERROR = -100;
+Fingerprint.prototype.BIOMETRIC_UNAVAILABLE = -101;
+Fingerprint.prototype.BIOMETRIC_AUTHENTICATION_FAILED = -102;
+Fingerprint.prototype.BIOMETRIC_SDK_NOT_SUPPORTED = -103;
+Fingerprint.prototype.BIOMETRIC_HARDWARE_NOT_SUPPORTED = -104;
+Fingerprint.prototype.BIOMETRIC_PERMISSION_NOT_GRANTED = -105;
+Fingerprint.prototype.BIOMETRIC_NOT_ENROLLED = -106;
+Fingerprint.prototype.BIOMETRIC_INTERNAL_PLUGIN_ERROR = -107;
+Fingerprint.prototype.BIOMETRIC_DISMISSED = -108;
+Fingerprint.prototype.BIOMETRIC_PIN_OR_PATTERN_DISMISSED = -109;
+Fingerprint.prototype.BIOMETRIC_SCREEN_GUARD_UNSECURED = -110;
+Fingerprint.prototype.BIOMETRIC_LOCKED_OUT = -111;
+Fingerprint.prototype.BIOMETRIC_LOCKED_OUT_PERMANENT = -112;
+
+// Biometric types
+Fingerprint.prototype.BIOMETRIC_TYPE_FINGERPRINT = "finger";
+Fingerprint.prototype.BIOMETRIC_TYPE_FACE = "face";
+Fingerprint.prototype.BIOMETRIC_TYPE_COMMON = "biometric";
 
 Fingerprint.prototype.show = function (params, successCallback, errorCallback) {
   cordova.exec(
index 8734bac..99f7154 100644 (file)
@@ -1,14 +1,4 @@
 {
-  "cordova-plugin-fingerprint-aio": {
-    "source": {
-      "type": "registry",
-      "id": "cordova-plugin-fingerprint-aio"
-    },
-    "is_top_level": true,
-    "variables": {
-      "FACEID_USAGE_DESCRIPTION": "认证中..."
-    }
-  },
   "cordova-plugin-touch-id": {
     "source": {
       "type": "registry",
     },
     "is_top_level": true,
     "variables": {}
+  },
+  "cordova-plugin-fingerprint-aio": {
+    "source": {
+      "type": "registry",
+      "id": "cordova-plugin-fingerprint-aio"
+    },
+    "is_top_level": true,
+    "variables": {}
   }
 }
\ No newline at end of file
index 22f9574..523315b 100644 (file)
     "cordova-plugin-advanced-http": {
       "PACKAGE_NAME": "$(PRODUCT_BUNDLE_IDENTIFIER)"
     },
-    "cordova-plugin-fingerprint-aio": {
-      "FACEID_USAGE_DESCRIPTION": "认证中...",
-      "PACKAGE_NAME": "$(PRODUCT_BUNDLE_IDENTIFIER)"
-    },
     "cordova-plugin-statusbar": {
       "PACKAGE_NAME": "$(PRODUCT_BUNDLE_IDENTIFIER)"
     },
     },
     "cordova-plugin-file": {
       "PACKAGE_NAME": "$(PRODUCT_BUNDLE_IDENTIFIER)"
+    },
+    "cordova-plugin-fingerprint-aio": {
+      "FACEID_USAGE_DESCRIPTION": " ",
+      "PACKAGE_NAME": "$(PRODUCT_BUNDLE_IDENTIFIER)"
     }
   },
   "dependent_plugins": {
index 9e2560a..0cd8b52 100644 (file)
     <link rel="stylesheet" type="text/css" href="css/aui.css">
     <link rel="stylesheet" type="text/css" href="css/weui.min.css">
     <link rel="stylesheet" type="text/css" href="css/jquery-weui.min.css">
-    <title>手机验证码</title>
+    <title>签约</title>
 </head>
 <body>
     <header class="aui-bar aui-bar-nav" style="padding-top:25px;">
         <a class="aui-pull-left" href="javascript:window.history.back()">
             <span class="aui-iconfont aui-icon-left"></span>
         </a>
-        <div class="aui-title">手机验证码</div>
+        <div class="aui-title">签约</div>
     </header>
     <div>
         <div class="weui-panel__hd">已发送验证码到您的手机:<span id="phone"></span></div>
                 </div>
             </div>
         </div>
+        <div>
+            <label for="agree" class="weui-agree" style="padding: .5em 5px .5em 15px;display: inline-block;">
+                <input id="agree" type="checkbox" class="weui-agree__checkbox" value="1" checked="checked">
+                <span class="weui-agree__text">
+                    我已仔细阅读并同意
+                </span>
+            </label>
+            <a href="signxy.html" style="font-size: 13px;">《市民卡免密代扣签约协议》</a>
+        </div>
         <section class="aui-content-padded" style="margin-top: 30px;">
-            <div class="aui-btn aui-btn-block aui-btn-info" tapmode onclick="app.doNext()">验证</div>
+            <div class="aui-btn aui-btn-block aui-btn-info" tapmode onclick="app.doNext()">签约</div>
         </section>
     </div>
 </body>
index f7e91a2..7af7d38 100644 (file)
@@ -81,9 +81,15 @@ var app = {
                     window.localStorage.setItem("idno", idno);
                     window.localStorage.setItem("phoneX",ret.phonex);
                     window.localStorage.setItem("personid", ret.personid);
+                    window.localStorage.setItem("userid", ret.personid);
                     window.localStorage.setItem("signed", ret.signed);
                     window.localStorage.setItem("paypwdset", ret.paypwdset);
-                    window.location = "bindcheck.html";
+                    if(ret.signed=='yes'){
+                        window.location = "main.html"
+                    }else{
+                        window.location = "bindcheck.html";
+                    }
+                    
                 } else {
                     if (ret.code == -1) {
                         $.alert(ret.msg, "提示", function() {
index 32dba4c..8862e73 100644 (file)
@@ -18,19 +18,10 @@ var app = {
         btnTime('codebtn');
     },
     getCode: function() {
-        var name = window.localStorage.getItem("name");
-        var cardno = window.localStorage.getItem("cardno");
-        var idtype = window.localStorage.getItem("idtype");
-        var idno = window.localStorage.getItem("idno");
-
         $.showLoading("正在请求");
         var param = {
-            "cardno": cardno,
-            "idtype": idtype,
-            "name": name,
-            "idno": idno
         }
-        V1Bindcard(param, function(ok, ret) {
+        V1Bindcardcode(param, function(ok, ret) {
             if (ok) {
                 $.hideLoading();
                 if (ret.code == 200) {
@@ -57,37 +48,27 @@ var app = {
         if(isEmpty(code)){
             return;
         }
-        var personid = window.localStorage.getItem("personid");
+        var agree = $("input[type=checkbox]:checked").val();
+        if(isEmpty(agree)){
+            $.alert("请同意市民卡免密代扣签约协议", "提示");
+            return;
+        }
         $.showLoading("正在处理");
         var param={
-            "personid":personid,
-            "code":code,
+            "agree":code
         }
-        V1Checkcode(param,function(ok,ret){
-            if(ok){
-                $.hideLoading();
-                console.log(ret)
+        V1Signbxy(param,function(ok, ret, err) {
+            if (ok) {
+                $.hideLoading(); 
                 if(ret.code==200){
-                    window.localStorage.setItem("paypwdtype", "new");
-                    window.localStorage.setItem("userid", personid);
-                    var signed =  window.localStorage.getItem("signed");
-                    var paypwdset =  window.localStorage.getItem("paypwdset");
-                    console.log(paypwdset)
-                    if (!paypwdset||'false'==paypwdset) {
-                        window.location = "paypwdset.html";
-                    } else {
-                        if (!isEmpty(signed) && signed == 'yes') {
-                            window.location = 'main.html'
-                        } else {
-                            window.location = 'signxy.html'
-                        }
-                    }
+                    window.localStorage.setItem("signed",ret.signed); 
+                    window.location="main.html";
                 }else{
-                     $.alert(ret.msg, "错误");
-                } 
-            }else{
+                    $.alert(ret.msg, "错误");
+                }
+            } else {
                 $.hideLoading();
-                $.alert("请求失败了"+ret.status+",请稍后再试", "错误");
+                $.alert("请求失败了:" + ret.status+"请稍后再试", "错误");
             }
         })
     }
index 7931a48..88950f3 100644 (file)
@@ -7,6 +7,29 @@ var app = {
   
     onDeviceReady: function() {
         this.receivedEvent('deviceready');
+        this.loginWithFinger();
+    },
+    loginWithFinger:function(){
+        let loginfinger =  window.localStorage.getItem("loginfinger");
+        let phone =  window.localStorage.getItem("phone");
+        let pwd =  window.localStorage.getItem("localpwd");
+        let _this = this;
+        if(phone&&pwd&&loginfinger&&loginfinger=='1'){
+              Fingerprint.isAvailable(function(result){
+                 Fingerprint.show({
+                       title:"正在使用指纹或人脸登录",
+                       description: "请验证您的指纹或人脸"
+                     }, function(success){
+                        _this.loginIt(phone,pwd);
+                     }, function(error){
+                       $.alert("验证失败,指纹或人脸错误,请使用密码登录", "提示");
+                       //$("#login").removeAttr("checked");
+                     });
+
+             }, function(message){
+                  $.alert("设备不支持指纹或人脸,请使用密码登录", "提示");
+             });
+        }
     },
 
     // Update DOM on a Received Event
@@ -29,7 +52,9 @@ var app = {
         if(isEmpty(phone)||isEmpty(pwd)){
             return;
         }
-        //loadingElement('loginBtn', '登录中...')
+        this.loginIt(phone,pwd);
+    },
+    loginIt: function(phone,pwd){
         $.showLoading("登录中");
         var param={
             "username":phone,
@@ -56,6 +81,7 @@ var app = {
                  window.localStorage.setItem("signed",ret.signed); 
                  window.localStorage.setItem("paypwdset",ret.paypwdset); 
                  window.localStorage.setItem("name",ret.name);  
+                 window.localStorage.setItem("localpwd",pwd);  
                  window.location = "main.html";  
                }     
             }else{
index bc93d91..78b896f 100644 (file)
@@ -111,6 +111,25 @@ var app = {
                 })
             })
         });
+        $('#accsignbtn').click(function() {
+            app.checkBefore(function() {
+                var signed = window.localStorage.getItem("signed");
+                var cum = new auiDialog({});
+                 if (isEmpty(signed) || signed != 'yes') {
+                    var confirm = cum.alert({
+                        title: "提示",
+                        msg: '您尚未签约市民卡免密代扣签约协议,无法使用该功能',
+                        buttons: ['取消', '去签约']
+                    }, function(ret) {
+                        if (ret.buttonIndex == 2) {
+                           app.toSignCode();
+                        }
+                    })
+                }else{
+                    window.location = 'signxycheck.html'
+                }
+            })
+        });
         this.initData();
         this.backBtn();
     },
@@ -153,13 +172,15 @@ var app = {
         $("#loaddata").show()
         $("#nodata").hide();
         var param = {
-            "pageno": 1
+            "pageno": 1,
+            "platform":device.platform
         }
         V1Bills(param, function(ok, ret) {
             if (ok) {
-                //console.log(ret)
+                console.log(ret)
                 if (ret.code == 200) {
-                    app.checkVersion(ret.version,ret.minversion,ret.versionmsg);
+                    app.checkVersion(ret.version,ret.minversion,ret.versionmsg,ret.versionurl);
+                    //app.checkVersion("1.3.9","1","new func","https://shouji.baidu.com/software/26706357.html");
                     $("#maingt").text(ret.t + "!")
                     $("#user-amount").text(ret.amount)
                     $("#user-point").text(ret.point)
@@ -196,14 +217,21 @@ var app = {
             }
         })
     },
-    checkVersion:function(ver,minver,msg){
+    checkVersion:function(ver,minver,m,url){
         cordova.getAppVersion.getVersionNumber(function (version) {
             //alert(version);
-            if(version<minver){
-                //TODO 强制升级
-                alert("当前版本过低,为了不影响您的使用,请先升级");
-            }else if(ver>version){
-                alert("有新的版本");    
+            //alert(version);
+            if(ver>version){
+                var cum = new auiDialog({});
+                var confirm = cum.alert({
+                    title: "有新的版本",
+                    msg: m,
+                    buttons: ['取消', '去更新']
+                }, function(ret) {
+                    if (ret.buttonIndex == 2) {
+                       cordova.InAppBrowser.open(url, '_system', 'location=no,toolbar=yes,toolbarposition=top,closebuttoncaption=关闭');
+                    }
+                })  
             }
         });
     },
@@ -282,38 +310,40 @@ var app = {
         }
     },
     checkOther: function(callback) {
-        var payseted = window.localStorage.getItem("paypwdset");
         var signed = window.localStorage.getItem("signed");
         var cum = new auiDialog({});
-        console.log(payseted, signed)
-        if (isEmpty(payseted) || !payseted || payseted != 'true') {
+
+        if (isEmpty(signed) || signed != 'yes') {
             var confirm = cum.alert({
                 title: "提示",
-                msg: '您还没有设置支付密码,无法使用该功能',
-                buttons: ['取消', '去设置']
+                msg: '您尚未签约市民卡免密代扣签约协议,无法使用该功能',
+                buttons: ['取消', '去签约']
             }, function(ret) {
                 if (ret.buttonIndex == 2) {
-                    window.location = 'paypwdset.html'
+                   app.toSignCode();
                 }
             })
         } else {
-            if (isEmpty(signed) || signed != 'yes') {
-                var confirm = cum.alert({
-                    title: "提示",
-                    msg: '您尚未签约代扣免密付协议,无法使用该功能',
-                    buttons: ['取消', '去签约']
-                }, function(ret) {
-                    if (ret.buttonIndex == 2) {
-                        window.location = 'signxy.html'
-                    }
-                })
-            } else {
-                if (callback) {
-                    callback()
-                }
+            if (callback) {
+                callback()
             }
         }
     },
+    toSignCode: function(){
+        var param = {
+        }
+        V1Bindcardcode(param, function(ok, ret) {
+            if (ok) {
+                if (ret.code == 200) {
+                    window.location = 'bindcheck.html'
+                } else {
+                    $.alert(ret.msg, "错误");
+                }
+            } else {
+                $.alert("请求失败了 " + ret.status + ",请稍后再试", "错误");
+            }
+        })
+    },
     toSign: function() {
         window.location = 'signxycheck.html'
     },
index b9d81b9..51b2aa1 100644 (file)
@@ -22,6 +22,10 @@ var app = {
             console.log(err);
           });
         }
+        document.addEventListener("backbutton", function(e){
+               e.preventDefault();
+               app.backTo();
+            }, false);
     },
     loadQrcode: function() {
         $.showLoading("加载中");
@@ -62,6 +66,7 @@ var app = {
             if (ok) {
                 if (ret.code == 200) {
                     $.hideLoading();
+                    $("#qrcode").html('');
                     var qrcode = new QRCode(document.getElementById("qrcode"), {
                       text: ret.qrcode,
                       width: 200,
index dd5475d..d159a40 100644 (file)
@@ -5,23 +5,68 @@ var app = {
         document.addEventListener('deviceready', this.onDeviceReady.bind(this), false);
     },
     onDeviceReady: function() {
+      let loginfinger =  window.localStorage.getItem("loginfinger");
+       if(loginfinger&&loginfinger=='1'){
+        $("#login").prop("checked","checked");
+       }
     },
     editPwd: function() {
        window.location = "editpwd.html";
     },
     toPayPwd: function() {
-       window.location = "paypwdmng.html";
+      var payseted = window.localStorage.getItem("paypwdset");
+      if (isEmpty(payseted) || !payseted || payseted != 'true') {
+          window.location = 'paypwdset.html'
+      } else{
+        window.location = "paypwdmng.html";
+      }
     },
     logout:function(){
         window.localStorage.removeItem("token");
         window.location = "login.html";
     },
     loginByTouchId: function() {
-       Fingerprint.isAvailable(function(result){
-            $.alert("设备不支持指纹", "提示");
-       }, function(message){
-            alert(message);
-       });
+       let loginfinger =  window.localStorage.getItem("loginfinger");
+       if(loginfinger&&loginfinger=='1'){
+          var confirm = new auiDialog({}).alert({
+                title: "提示",
+                msg: '确定关闭指纹或人脸登录吗?',
+                buttons: ['取消', '确定']
+            }, function(ret) {
+                if (ret.buttonIndex == 2) {
+                    window.localStorage.setItem("loginfinger","0");
+                    $("#login").removeAttr("checked");
+                }else{
+                  //$("#login").attr("checked","checked");
+                }
+               });
+       }else{
+        let pwd =  window.localStorage.getItem("localpwd");
+        if(!pwd){
+          $.alert("长时间未登录,需要先登录后再使用该功能", "提示",function(){
+             window.localStorage.removeItem("token");
+             window.location = "login.html";
+          });
+          return;
+        }
+         $("#login").removeAttr("checked");
+         Fingerprint.isAvailable(function(result){
+             Fingerprint.show({
+                   title:"大理市民卡开启指纹或人脸登录",
+                   description: "请验证您的指纹或人脸"
+                 }, function(success){
+                    window.localStorage.setItem("loginfinger","1");
+                    $.alert("验证成功,您已开启指纹或人脸登录", "提示");
+                    $("#login").prop("checked","checked");
+                 }, function(error){
+                   $.alert("验证失败,指纹或人脸错误次数过多,请稍后再试", "提示");
+                   //$("#login").removeAttr("checked");
+                 });
+
+         }, function(message){
+              $.alert("设备不支持指纹或人脸", "提示");
+         });
+       }
     }
 };
 app.initialize();
index 3e8ae05..426bf2d 100644 (file)
@@ -1,4 +1,4 @@
-var dev = true;
+var dev = false;
 var SERVER = "https://yy.dlsmk.cn/payapi/mobileapi";
 var DOOR_URl = "https://yy.dlsmk.cn/door/app/appMintUIindex";//门禁服务地址
 var GLOBAL_TODAY="";
@@ -7,6 +7,10 @@ var CURRENT_INDEX=1;
 if (dev) {
     SERVER = "http://172.28.43.7:8099/payapi/mobileapi";
 }
+function V1Bindcardcode(param,callback) {
+    ajaxPost("/v1/bindcardcode", param, callback)
+}
+
 function V1Unbindcard(param,callback){
     ajaxPost("/v1/unbindcard", param, callback)
 }
index f97f3d4..4ee8598 100644 (file)
@@ -14,10 +14,10 @@ var app = {
                 if(ret.code==200){
                     $("#content").html(ret.page);
                     if(isEmpty(ret.signed)||ret.signed!='yes'){
-                        $("#btn").show();   
-                        $("#content").css("bottom","135px");
+                        //$("#btn").show();   
+                        //$("#content").css("bottom","135px");
                     }else{
-                        $("#content").css("bottom","10px");
+                        //$("#content").css("bottom","10px");
                     }
                 }else{
                     $.alert(ret.msg, "错误");
diff --git a/www/js/unsignedcheck.js b/www/js/unsignedcheck.js
new file mode 100644 (file)
index 0000000..ce72038
--- /dev/null
@@ -0,0 +1,71 @@
+var dict;
+var app = {
+
+    // Application Constructor
+    initialize: function() {
+        document.addEventListener('deviceready', this.onDeviceReady.bind(this), false);
+    },
+    onDeviceReady: function() {
+        var phone = window.localStorage.getItem("phoneX");
+        if(!isEmpty(phone)){
+            $("#phone").text(phone)
+        }else{
+            phone =  window.localStorage.getItem("phone");
+            $("#phone").text(phone)
+        }
+        app.getCode();
+    },
+    getCode: function() {
+        $.showLoading("正在请求");
+        var param = {
+        }
+        V1Bindcardcode(param, function(ok, ret) {
+            if (ok) {
+                $.hideLoading();
+                if (ret.code == 200) {
+                   $("#codebtn").attr("disabled","disabled")
+                   $("#codebtn").addClass("vcodedisabled")
+                   btnTime('codebtn');
+                } else {
+                    if (ret.code == -1) {
+                        $.alert(ret.msg, "提示", function() {
+                            window.location = "main.html"
+                        });
+                    } else {
+                        $.alert(ret.msg, "错误");
+                    }
+                }
+            } else {
+                $.hideLoading();
+                $.alert("请求失败了 " + ret.status + ",请稍后再试", "错误");
+            }
+        })
+    },
+    doNext: function() {
+        var code =  $("#code").val();
+        if(isEmpty(code)){
+            return;
+        }
+        $.showLoading("正在处理");
+        var param={
+            "code":code
+        }
+        V1UnSignbxy(param, function(ok, ret, err) {
+            if (ok) {
+                $.hideLoading();
+                if (ret.code == 200) {
+                    window.localStorage.setItem("signed", ret.signed);
+                    $.alert('解除成功', "提示", function() {
+                        window.location = 'main.html'
+                    });
+                } else {
+                    $.alert(ret.msg, "错误");
+                }
+            } else {
+                $.hideLoading();
+                $.alert("请求失败了:" + ret.status + "请稍后再试", "错误");
+            }
+        })
+    }
+};
+app.initialize();
\ No newline at end of file
index b357ca3..c8bb590 100644 (file)
                         <div class="aui-list-item-right" id="userbank"></div>
                     </div>
                 </li>
-                <li class="aui-list-item" onclick="app.toSign()">
+                <li class="aui-list-item" id="accsignbtn">
                     <div class="aui-list-item-label-icon">
                         <i class="aui-iconfont aui-icon-pencil aui-text-danger"></i>
                     </div>
index 5ce5788..a64f153 100644 (file)
@@ -24,9 +24,9 @@
         <div style="background: #fff;text-align: center;" id="qrcode"></div>
     </div>
     <p style="text-align: center;margin-top:40px;color:#999">请将二维码对准扫描设备</p>
-    <!--<div style="padding: 30px;">
-        <div class="aui-btn aui-btn-block aui-btn-info" tapmode onclick="window.location.reload();">刷新二维码</div>
-    </div>-->
+    <div style="padding: 30px;">
+        <div class="aui-btn aui-btn-block aui-btn-info" tapmode onclick="app.refresh()">刷新二维码</div>
+    </div>
 </body>
 </html>
 <script type="text/javascript" src="cordova.js"></script>
index b205cdb..971cc59 100644 (file)
             </li>
             <li class="aui-list-item" onclick="app.loginByTouchId()">
                 <div class="aui-list-item-label-icon">
-                    <i class="aui-iconfont aui-icon-lock aui-text-info"></i>
+                    <i class="aui-iconfont aui-icon-gear aui-text-info"></i>
                 </div>
                 <div class="aui-list-item-inner ">
                     <div class="aui-list-item-title">指纹\人脸登录</div>
-                    <div class="aui-list-item-right"><input type="checkbox" id="login" class="aui-switch" ></div>
+                    <div class="aui-list-item-right"><input type="checkbox" id="login" class="aui-switch" disabled ></div>
                 </div>
             </li>
+        </ul>
+    </section>
+    <section class="aui-content aui-margin-b-15 aui-margin-t-10">
+        <ul class="aui-list aui-list-in aui-margin-t-10 ">
             <li class="aui-list-item" onclick="app.toPayPwd()">
                 <div class="aui-list-item-label-icon">
                     <i class="aui-iconfont aui-icon-pencil aui-text-danger"></i>
index cb0f1ba..c22eda3 100644 (file)
     <link rel="stylesheet" type="text/css" href="css/aui.css">
     <link rel="stylesheet" type="text/css" href="css/weui.min.css">
     <link rel="stylesheet" type="text/css" href="css/jquery-weui.min.css">
-    <title>签约代扣免密支付协议</title>
+    <title>市民卡免密代扣签约协议</title>
 </head>
 <body>
     <header class="aui-bar aui-bar-nav" style="padding-top:25px;">
-        <a class="aui-pull-left" href="main.html">
+        <a class="aui-pull-left" href="javascript:window.history.back()">
             <span class="aui-iconfont aui-icon-left"></span>
         </a>
-        <div class="aui-title">签约代扣免密支付协议</div>
+        <div class="aui-title">市民卡免密代扣签约协议</div>
     </header>
-    <div style="padding:10px;overflow: scroll;position: absolute;top:74px;bottom:135px;left: 0;right: 0" id="content">
+    <div style="padding:10px;overflow: scroll;position: absolute;top:74px;bottom:10px;left: 0;right: 0" id="content">
         
     </div>
-    <div class="weui-footer weui-footer_fixed-bottom" style="background: #fff;display: none;" id="btn">
-            <div style="margin-top: 10px;">
-                <label for="agree" class="weui-agree" style="padding: .5em 5px .5em 15px;display: inline-block;">
-                    <input id="agree" type="checkbox" class="weui-agree__checkbox" value="yes">
-                    <span class="weui-agree__text">
-                        我已阅读并同意该协议
-                    </span>
-                </label>
-            </div>
-            <section class="aui-content-padded" style="margin-top: 20px;">
-                <div class="aui-btn aui-btn-block aui-btn-info"  tapmode onclick="app.agreeXY()">签约代扣协议</div>
-            </section>
-    </div>
+   
 </body>
 
 </html>
diff --git a/www/unsignedcheck.html b/www/unsignedcheck.html
new file mode 100644 (file)
index 0000000..f677648
--- /dev/null
@@ -0,0 +1,48 @@
+<!DOCTYPE html>
+<html>
+
+<head>
+    <link rel="stylesheet" type="text/css" href="mobileui/style.css">
+    <meta name="format-detection" content="telephone=no">
+    <meta charset="utf-8">
+    <meta name="msapplication-tap-highlight" content="no">
+    <meta name="viewport" content="viewport-fit=cover, initial-scale=1, maximum-scale=1, user-scalable=no, width=device-width" />
+    <link rel="stylesheet" type="text/css" href="css/index.css">
+    <link rel="stylesheet" type="text/css" href="css/aui.css">
+    <link rel="stylesheet" type="text/css" href="css/weui.min.css">
+    <link rel="stylesheet" type="text/css" href="css/jquery-weui.min.css">
+    <title>解约</title>
+</head>
+<body>
+    <header class="aui-bar aui-bar-nav" style="padding-top:25px;">
+        <a class="aui-pull-left" href="javascript:window.history.back()">
+            <span class="aui-iconfont aui-icon-left"></span>
+        </a>
+        <div class="aui-title">解约</div>
+    </header>
+    <div>
+        <div class="weui-panel__hd">已发送验证码到您的手机:<span id="phone"></span></div>
+        <div class="weui-cells weui-cells_form">
+            <div class="weui-cell weui-cell_vcode" style="padding:0 10px; ">
+                <div class="weui-cell__hd">
+                    <label class="weui-label" style="width: 80px;font-size: 14px;">验证码</label>
+                </div>
+                <div class="weui-cell__bd">
+                    <input class="weui-input" type="tel" id="code" style="font-size: 14px;" placeholder="请输入验证码" maxlength="6">
+                </div>
+                <div class="weui-cell__ft">
+                    <button class="weui-vcode-btn" onclick="app.getCode()" id="codebtn" style="width: 100px;height: 1rem;font-size: 14px;">获取验证码</button>
+                </div>
+            </div>
+        </div>
+        <section class="aui-content-padded" style="margin-top: 30px;">
+            <div class="aui-btn aui-btn-block aui-btn-info" tapmode onclick="app.doNext()">解约</div>
+        </section>
+    </div>
+</body>
+</html>
+<script type="text/javascript" src="cordova.js"></script>
+<script type="text/javascript" src="js/lib/jquery-2.1.4.js"></script>
+<script type="text/javascript" src="js/lib/jquery-weui.js"></script>
+<script type="text/javascript" src="js/server.js"></script>
+<script type="text/javascript" src="js/unsignedcheck.js"></script>
\ No newline at end of file