@capgo/capacitor-native-biometric 6.0.4 → 7.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CapgoCapacitorNativeBiometric.podspec +1 -1
- package/README.md +30 -35
- package/android/build.gradle +7 -7
- package/android/gradle/wrapper/gradle-wrapper.jar +0 -0
- package/android/gradle/wrapper/gradle-wrapper.properties +1 -1
- package/android/gradlew +13 -9
- package/android/gradlew.bat +12 -10
- package/android/src/main/java/ee/forgr/biometric/AuthActivity.java +49 -15
- package/android/src/main/java/ee/forgr/biometric/NativeBiometric.java +56 -53
- package/dist/docs.json +57 -43
- package/dist/esm/definitions.d.ts +7 -0
- package/dist/esm/definitions.js.map +1 -1
- package/dist/esm/web.js +4 -0
- package/dist/esm/web.js.map +1 -1
- package/dist/plugin.cjs.js +4 -0
- package/dist/plugin.cjs.js.map +1 -1
- package/dist/plugin.js +4 -0
- package/dist/plugin.js.map +1 -1
- package/ios/Plugin/Plugin.swift +10 -2
- package/ios/Plugin.xcodeproj/project.pbxproj +4 -12
- package/ios/Podfile +1 -1
- package/package.json +49 -42
- package/ios/Plugin/Plugin.h +0 -10
- package/ios/Plugin/Plugin.m +0 -12
- package/ios/Podfile.lock +0 -22
- package/ios/Pods/Local Podspecs/Capacitor.podspec.json +0 -31
- package/ios/Pods/Local Podspecs/CapacitorCordova.podspec.json +0 -29
- package/ios/Pods/Manifest.lock +0 -22
- package/ios/Pods/Pods.xcodeproj/project.pbxproj +0 -1610
- package/ios/Pods/Target Support Files/Capacitor/Capacitor-Info.plist +0 -26
- package/ios/Pods/Target Support Files/Capacitor/Capacitor-dummy.m +0 -5
- package/ios/Pods/Target Support Files/Capacitor/Capacitor-prefix.pch +0 -12
- package/ios/Pods/Target Support Files/Capacitor/Capacitor-umbrella.h +0 -23
- package/ios/Pods/Target Support Files/Capacitor/Capacitor.debug.xcconfig +0 -16
- package/ios/Pods/Target Support Files/Capacitor/Capacitor.modulemap +0 -8
- package/ios/Pods/Target Support Files/Capacitor/Capacitor.release.xcconfig +0 -16
- package/ios/Pods/Target Support Files/CapacitorCordova/CapacitorCordova-Info.plist +0 -26
- package/ios/Pods/Target Support Files/CapacitorCordova/CapacitorCordova-dummy.m +0 -5
- package/ios/Pods/Target Support Files/CapacitorCordova/CapacitorCordova-prefix.pch +0 -12
- package/ios/Pods/Target Support Files/CapacitorCordova/CapacitorCordova-umbrella.h +0 -32
- package/ios/Pods/Target Support Files/CapacitorCordova/CapacitorCordova.debug.xcconfig +0 -13
- package/ios/Pods/Target Support Files/CapacitorCordova/CapacitorCordova.modulemap +0 -6
- package/ios/Pods/Target Support Files/CapacitorCordova/CapacitorCordova.release.xcconfig +0 -13
- package/ios/Pods/Target Support Files/Pods-Plugin/Pods-Plugin-Info.plist +0 -26
- package/ios/Pods/Target Support Files/Pods-Plugin/Pods-Plugin-acknowledgements.markdown +0 -53
- package/ios/Pods/Target Support Files/Pods-Plugin/Pods-Plugin-acknowledgements.plist +0 -91
- package/ios/Pods/Target Support Files/Pods-Plugin/Pods-Plugin-dummy.m +0 -5
- package/ios/Pods/Target Support Files/Pods-Plugin/Pods-Plugin-umbrella.h +0 -16
- package/ios/Pods/Target Support Files/Pods-Plugin/Pods-Plugin.debug.xcconfig +0 -14
- package/ios/Pods/Target Support Files/Pods-Plugin/Pods-Plugin.modulemap +0 -6
- package/ios/Pods/Target Support Files/Pods-Plugin/Pods-Plugin.release.xcconfig +0 -14
- package/ios/Pods/Target Support Files/Pods-PluginTests/Pods-PluginTests-Info.plist +0 -26
- package/ios/Pods/Target Support Files/Pods-PluginTests/Pods-PluginTests-acknowledgements.markdown +0 -53
- package/ios/Pods/Target Support Files/Pods-PluginTests/Pods-PluginTests-acknowledgements.plist +0 -91
- package/ios/Pods/Target Support Files/Pods-PluginTests/Pods-PluginTests-dummy.m +0 -5
- package/ios/Pods/Target Support Files/Pods-PluginTests/Pods-PluginTests-frameworks.sh +0 -188
- package/ios/Pods/Target Support Files/Pods-PluginTests/Pods-PluginTests-umbrella.h +0 -16
- package/ios/Pods/Target Support Files/Pods-PluginTests/Pods-PluginTests.debug.xcconfig +0 -15
- package/ios/Pods/Target Support Files/Pods-PluginTests/Pods-PluginTests.modulemap +0 -6
- package/ios/Pods/Target Support Files/Pods-PluginTests/Pods-PluginTests.release.xcconfig +0 -15
|
@@ -8,6 +8,6 @@
|
|
|
8
8
|
s.author = 'Martin Donadieu'
|
|
9
9
|
s.source = { :git => 'https://github.com/Cap-go/capacitor-native-biometric', :tag => s.version.to_s }
|
|
10
10
|
s.source_files = 'ios/Plugin/**/*.{swift,h,m,c,cc,mm,cpp}'
|
|
11
|
-
s.ios.deployment_target
|
|
11
|
+
s.ios.deployment_target = '14.0'
|
|
12
12
|
s.dependency 'Capacitor'
|
|
13
13
|
end
|
package/README.md
CHANGED
|
@@ -92,7 +92,7 @@ This is a plugin specific list of error codes that can be thrown on verifyIdenti
|
|
|
92
92
|
### isAvailable(...)
|
|
93
93
|
|
|
94
94
|
```typescript
|
|
95
|
-
isAvailable(options?: IsAvailableOptions | undefined) =>
|
|
95
|
+
isAvailable(options?: IsAvailableOptions | undefined) => Promise<AvailableResult>
|
|
96
96
|
```
|
|
97
97
|
|
|
98
98
|
Checks if biometric authentication hardware is available.
|
|
@@ -101,7 +101,7 @@ Checks if biometric authentication hardware is available.
|
|
|
101
101
|
| ------------- | ----------------------------------------------------------------- |
|
|
102
102
|
| **`options`** | <code><a href="#isavailableoptions">IsAvailableOptions</a></code> |
|
|
103
103
|
|
|
104
|
-
**Returns:** <code>
|
|
104
|
+
**Returns:** <code>Promise<<a href="#availableresult">AvailableResult</a>></code>
|
|
105
105
|
|
|
106
106
|
**Since:** 1.0.0
|
|
107
107
|
|
|
@@ -111,7 +111,7 @@ Checks if biometric authentication hardware is available.
|
|
|
111
111
|
### verifyIdentity(...)
|
|
112
112
|
|
|
113
113
|
```typescript
|
|
114
|
-
verifyIdentity(options?: BiometricOptions | undefined) =>
|
|
114
|
+
verifyIdentity(options?: BiometricOptions | undefined) => Promise<void>
|
|
115
115
|
```
|
|
116
116
|
|
|
117
117
|
Prompts the user to authenticate with biometrics.
|
|
@@ -120,8 +120,6 @@ Prompts the user to authenticate with biometrics.
|
|
|
120
120
|
| ------------- | ------------------------------------------------------------- |
|
|
121
121
|
| **`options`** | <code><a href="#biometricoptions">BiometricOptions</a></code> |
|
|
122
122
|
|
|
123
|
-
**Returns:** <code>any</code>
|
|
124
|
-
|
|
125
123
|
**Since:** 1.0.0
|
|
126
124
|
|
|
127
125
|
--------------------
|
|
@@ -130,7 +128,7 @@ Prompts the user to authenticate with biometrics.
|
|
|
130
128
|
### getCredentials(...)
|
|
131
129
|
|
|
132
130
|
```typescript
|
|
133
|
-
getCredentials(options: GetCredentialOptions) =>
|
|
131
|
+
getCredentials(options: GetCredentialOptions) => Promise<Credentials>
|
|
134
132
|
```
|
|
135
133
|
|
|
136
134
|
Gets the stored credentials for a given server.
|
|
@@ -139,7 +137,7 @@ Gets the stored credentials for a given server.
|
|
|
139
137
|
| ------------- | --------------------------------------------------------------------- |
|
|
140
138
|
| **`options`** | <code><a href="#getcredentialoptions">GetCredentialOptions</a></code> |
|
|
141
139
|
|
|
142
|
-
**Returns:** <code>
|
|
140
|
+
**Returns:** <code>Promise<<a href="#credentials">Credentials</a>></code>
|
|
143
141
|
|
|
144
142
|
**Since:** 1.0.0
|
|
145
143
|
|
|
@@ -149,7 +147,7 @@ Gets the stored credentials for a given server.
|
|
|
149
147
|
### setCredentials(...)
|
|
150
148
|
|
|
151
149
|
```typescript
|
|
152
|
-
setCredentials(options: SetCredentialOptions) =>
|
|
150
|
+
setCredentials(options: SetCredentialOptions) => Promise<void>
|
|
153
151
|
```
|
|
154
152
|
|
|
155
153
|
Stores the given credentials for a given server.
|
|
@@ -158,8 +156,6 @@ Stores the given credentials for a given server.
|
|
|
158
156
|
| ------------- | --------------------------------------------------------------------- |
|
|
159
157
|
| **`options`** | <code><a href="#setcredentialoptions">SetCredentialOptions</a></code> |
|
|
160
158
|
|
|
161
|
-
**Returns:** <code>any</code>
|
|
162
|
-
|
|
163
159
|
**Since:** 1.0.0
|
|
164
160
|
|
|
165
161
|
--------------------
|
|
@@ -168,7 +164,7 @@ Stores the given credentials for a given server.
|
|
|
168
164
|
### deleteCredentials(...)
|
|
169
165
|
|
|
170
166
|
```typescript
|
|
171
|
-
deleteCredentials(options: DeleteCredentialOptions) =>
|
|
167
|
+
deleteCredentials(options: DeleteCredentialOptions) => Promise<void>
|
|
172
168
|
```
|
|
173
169
|
|
|
174
170
|
Deletes the stored credentials for a given server.
|
|
@@ -177,8 +173,6 @@ Deletes the stored credentials for a given server.
|
|
|
177
173
|
| ------------- | --------------------------------------------------------------------------- |
|
|
178
174
|
| **`options`** | <code><a href="#deletecredentialoptions">DeleteCredentialOptions</a></code> |
|
|
179
175
|
|
|
180
|
-
**Returns:** <code>any</code>
|
|
181
|
-
|
|
182
176
|
**Since:** 1.0.0
|
|
183
177
|
|
|
184
178
|
--------------------
|
|
@@ -187,13 +181,6 @@ Deletes the stored credentials for a given server.
|
|
|
187
181
|
### Interfaces
|
|
188
182
|
|
|
189
183
|
|
|
190
|
-
#### IsAvailableOptions
|
|
191
|
-
|
|
192
|
-
| Prop | Type | Description |
|
|
193
|
-
| ----------------- | -------------------- | ----------------------------------------------------------------------------------------------------- |
|
|
194
|
-
| **`useFallback`** | <code>boolean</code> | Specifies if should fallback to passcode authentication if biometric authentication is not available. |
|
|
195
|
-
|
|
196
|
-
|
|
197
184
|
#### AvailableResult
|
|
198
185
|
|
|
199
186
|
| Prop | Type |
|
|
@@ -203,25 +190,26 @@ Deletes the stored credentials for a given server.
|
|
|
203
190
|
| **`errorCode`** | <code>number</code> |
|
|
204
191
|
|
|
205
192
|
|
|
206
|
-
####
|
|
193
|
+
#### IsAvailableOptions
|
|
207
194
|
|
|
208
|
-
| Prop
|
|
209
|
-
|
|
|
210
|
-
| **`
|
|
211
|
-
| **`title`** | <code>string</code> | | |
|
|
212
|
-
| **`subtitle`** | <code>string</code> | | |
|
|
213
|
-
| **`description`** | <code>string</code> | | |
|
|
214
|
-
| **`negativeButtonText`** | <code>string</code> | | |
|
|
215
|
-
| **`useFallback`** | <code>boolean</code> | Specifies if should fallback to passcode authentication if biometric authentication fails. | |
|
|
216
|
-
| **`fallbackTitle`** | <code>string</code> | Only for iOS. Set the text for the fallback button in the authentication dialog. If this property is not specified, the default text is set by the system. | |
|
|
217
|
-
| **`maxAttempts`** | <code>number</code> | Only for Android. Set a maximum number of attempts for biometric authentication. The maximum allowed by android is 5. | <code>1</code> |
|
|
195
|
+
| Prop | Type | Description |
|
|
196
|
+
| ----------------- | -------------------- | ----------------------------------------------------------------------------------------------------- |
|
|
197
|
+
| **`useFallback`** | <code>boolean</code> | Specifies if should fallback to passcode authentication if biometric authentication is not available. |
|
|
218
198
|
|
|
219
199
|
|
|
220
|
-
####
|
|
200
|
+
#### BiometricOptions
|
|
221
201
|
|
|
222
|
-
| Prop
|
|
223
|
-
|
|
|
224
|
-
| **`
|
|
202
|
+
| Prop | Type | Description | Default |
|
|
203
|
+
| -------------------------- | --------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------- |
|
|
204
|
+
| **`reason`** | <code>string</code> | | |
|
|
205
|
+
| **`title`** | <code>string</code> | | |
|
|
206
|
+
| **`subtitle`** | <code>string</code> | | |
|
|
207
|
+
| **`description`** | <code>string</code> | | |
|
|
208
|
+
| **`negativeButtonText`** | <code>string</code> | | |
|
|
209
|
+
| **`useFallback`** | <code>boolean</code> | Specifies if should fallback to passcode authentication if biometric authentication fails. | |
|
|
210
|
+
| **`fallbackTitle`** | <code>string</code> | Only for iOS. Set the text for the fallback button in the authentication dialog. If this property is not specified, the default text is set by the system. | |
|
|
211
|
+
| **`maxAttempts`** | <code>number</code> | Only for Android. Set a maximum number of attempts for biometric authentication. The maximum allowed by android is 5. | <code>1</code> |
|
|
212
|
+
| **`allowedBiometryTypes`** | <code>BiometryType[]</code> | Only for Android. Specify which biometry types are allowed for authentication. If not specified, all available types will be allowed. | |
|
|
225
213
|
|
|
226
214
|
|
|
227
215
|
#### Credentials
|
|
@@ -232,6 +220,13 @@ Deletes the stored credentials for a given server.
|
|
|
232
220
|
| **`password`** | <code>string</code> |
|
|
233
221
|
|
|
234
222
|
|
|
223
|
+
#### GetCredentialOptions
|
|
224
|
+
|
|
225
|
+
| Prop | Type |
|
|
226
|
+
| ------------ | ------------------- |
|
|
227
|
+
| **`server`** | <code>string</code> |
|
|
228
|
+
|
|
229
|
+
|
|
235
230
|
#### SetCredentialOptions
|
|
236
231
|
|
|
237
232
|
| Prop | Type |
|
package/android/build.gradle
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
ext {
|
|
2
2
|
junitVersion = project.hasProperty('junitVersion') ? rootProject.ext.junitVersion : '4.13.2'
|
|
3
|
-
androidxJunitVersion = project.hasProperty('androidxJunitVersion') ? rootProject.ext.androidxJunitVersion : '1.1
|
|
4
|
-
androidxEspressoCoreVersion = project.hasProperty('androidxEspressoCoreVersion') ? rootProject.ext.androidxEspressoCoreVersion : '3.
|
|
5
|
-
androidxAppCompatVersion = project.hasProperty('androidxAppCompatVersion') ? rootProject.ext.androidxAppCompatVersion : '1.
|
|
3
|
+
androidxJunitVersion = project.hasProperty('androidxJunitVersion') ? rootProject.ext.androidxJunitVersion : '1.2.1'
|
|
4
|
+
androidxEspressoCoreVersion = project.hasProperty('androidxEspressoCoreVersion') ? rootProject.ext.androidxEspressoCoreVersion : '3.6.1'
|
|
5
|
+
androidxAppCompatVersion = project.hasProperty('androidxAppCompatVersion') ? rootProject.ext.androidxAppCompatVersion : '1.7.0'
|
|
6
6
|
}
|
|
7
7
|
|
|
8
8
|
buildscript {
|
|
@@ -11,7 +11,7 @@ buildscript {
|
|
|
11
11
|
mavenCentral()
|
|
12
12
|
}
|
|
13
13
|
dependencies {
|
|
14
|
-
classpath 'com.android.tools.build:gradle:8.2
|
|
14
|
+
classpath 'com.android.tools.build:gradle:8.7.2'
|
|
15
15
|
}
|
|
16
16
|
}
|
|
17
17
|
|
|
@@ -19,10 +19,10 @@ apply plugin: 'com.android.library'
|
|
|
19
19
|
|
|
20
20
|
android {
|
|
21
21
|
namespace "ee.forgr.biometric.capacitornativebiometric"
|
|
22
|
-
compileSdk project.hasProperty('compileSdkVersion') ? rootProject.ext.compileSdkVersion :
|
|
22
|
+
compileSdk project.hasProperty('compileSdkVersion') ? rootProject.ext.compileSdkVersion : 35
|
|
23
23
|
defaultConfig {
|
|
24
|
-
minSdkVersion project.hasProperty('minSdkVersion') ? rootProject.ext.minSdkVersion :
|
|
25
|
-
targetSdkVersion project.hasProperty('targetSdkVersion') ? rootProject.ext.targetSdkVersion :
|
|
24
|
+
minSdkVersion project.hasProperty('minSdkVersion') ? rootProject.ext.minSdkVersion : 23
|
|
25
|
+
targetSdkVersion project.hasProperty('targetSdkVersion') ? rootProject.ext.targetSdkVersion : 35
|
|
26
26
|
versionCode 1
|
|
27
27
|
versionName "1.0"
|
|
28
28
|
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
|
Binary file
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
distributionBase=GRADLE_USER_HOME
|
|
2
2
|
distributionPath=wrapper/dists
|
|
3
|
-
distributionUrl=https\://services.gradle.org/distributions/gradle-8.
|
|
3
|
+
distributionUrl=https\://services.gradle.org/distributions/gradle-8.11.1-all.zip
|
|
4
4
|
networkTimeout=10000
|
|
5
5
|
validateDistributionUrl=true
|
|
6
6
|
zipStoreBase=GRADLE_USER_HOME
|
package/android/gradlew
CHANGED
|
@@ -15,6 +15,8 @@
|
|
|
15
15
|
# See the License for the specific language governing permissions and
|
|
16
16
|
# limitations under the License.
|
|
17
17
|
#
|
|
18
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
19
|
+
#
|
|
18
20
|
|
|
19
21
|
##############################################################################
|
|
20
22
|
#
|
|
@@ -55,7 +57,7 @@
|
|
|
55
57
|
# Darwin, MinGW, and NonStop.
|
|
56
58
|
#
|
|
57
59
|
# (3) This script is generated from the Groovy template
|
|
58
|
-
# https://github.com/gradle/gradle/blob/HEAD/
|
|
60
|
+
# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
|
|
59
61
|
# within the Gradle project.
|
|
60
62
|
#
|
|
61
63
|
# You can find Gradle at https://github.com/gradle/gradle/.
|
|
@@ -83,7 +85,9 @@ done
|
|
|
83
85
|
# This is normally unused
|
|
84
86
|
# shellcheck disable=SC2034
|
|
85
87
|
APP_BASE_NAME=${0##*/}
|
|
86
|
-
|
|
88
|
+
# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
|
|
89
|
+
APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s
|
|
90
|
+
' "$PWD" ) || exit
|
|
87
91
|
|
|
88
92
|
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
|
89
93
|
MAX_FD=maximum
|
|
@@ -144,7 +148,7 @@ if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
|
|
|
144
148
|
case $MAX_FD in #(
|
|
145
149
|
max*)
|
|
146
150
|
# In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.
|
|
147
|
-
# shellcheck disable=SC3045
|
|
151
|
+
# shellcheck disable=SC2039,SC3045
|
|
148
152
|
MAX_FD=$( ulimit -H -n ) ||
|
|
149
153
|
warn "Could not query maximum file descriptor limit"
|
|
150
154
|
esac
|
|
@@ -152,7 +156,7 @@ if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
|
|
|
152
156
|
'' | soft) :;; #(
|
|
153
157
|
*)
|
|
154
158
|
# In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
|
|
155
|
-
# shellcheck disable=SC3045
|
|
159
|
+
# shellcheck disable=SC2039,SC3045
|
|
156
160
|
ulimit -n "$MAX_FD" ||
|
|
157
161
|
warn "Could not set maximum file descriptor limit to $MAX_FD"
|
|
158
162
|
esac
|
|
@@ -201,11 +205,11 @@ fi
|
|
|
201
205
|
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
|
202
206
|
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
|
|
203
207
|
|
|
204
|
-
# Collect all arguments for the java command
|
|
205
|
-
# *
|
|
206
|
-
#
|
|
207
|
-
#
|
|
208
|
-
#
|
|
208
|
+
# Collect all arguments for the java command:
|
|
209
|
+
# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
|
|
210
|
+
# and any embedded shellness will be escaped.
|
|
211
|
+
# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be
|
|
212
|
+
# treated as '${Hostname}' itself on the command line.
|
|
209
213
|
|
|
210
214
|
set -- \
|
|
211
215
|
"-Dorg.gradle.appname=$APP_BASE_NAME" \
|
package/android/gradlew.bat
CHANGED
|
@@ -13,6 +13,8 @@
|
|
|
13
13
|
@rem See the License for the specific language governing permissions and
|
|
14
14
|
@rem limitations under the License.
|
|
15
15
|
@rem
|
|
16
|
+
@rem SPDX-License-Identifier: Apache-2.0
|
|
17
|
+
@rem
|
|
16
18
|
|
|
17
19
|
@if "%DEBUG%"=="" @echo off
|
|
18
20
|
@rem ##########################################################################
|
|
@@ -43,11 +45,11 @@ set JAVA_EXE=java.exe
|
|
|
43
45
|
%JAVA_EXE% -version >NUL 2>&1
|
|
44
46
|
if %ERRORLEVEL% equ 0 goto execute
|
|
45
47
|
|
|
46
|
-
echo.
|
|
47
|
-
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
|
48
|
-
echo.
|
|
49
|
-
echo Please set the JAVA_HOME variable in your environment to match the
|
|
50
|
-
echo location of your Java installation.
|
|
48
|
+
echo. 1>&2
|
|
49
|
+
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2
|
|
50
|
+
echo. 1>&2
|
|
51
|
+
echo Please set the JAVA_HOME variable in your environment to match the 1>&2
|
|
52
|
+
echo location of your Java installation. 1>&2
|
|
51
53
|
|
|
52
54
|
goto fail
|
|
53
55
|
|
|
@@ -57,11 +59,11 @@ set JAVA_EXE=%JAVA_HOME%/bin/java.exe
|
|
|
57
59
|
|
|
58
60
|
if exist "%JAVA_EXE%" goto execute
|
|
59
61
|
|
|
60
|
-
echo.
|
|
61
|
-
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
|
|
62
|
-
echo.
|
|
63
|
-
echo Please set the JAVA_HOME variable in your environment to match the
|
|
64
|
-
echo location of your Java installation.
|
|
62
|
+
echo. 1>&2
|
|
63
|
+
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2
|
|
64
|
+
echo. 1>&2
|
|
65
|
+
echo Please set the JAVA_HOME variable in your environment to match the 1>&2
|
|
66
|
+
echo location of your Java installation. 1>&2
|
|
65
67
|
|
|
66
68
|
goto fail
|
|
67
69
|
|
|
@@ -6,13 +6,14 @@ import android.os.Bundle;
|
|
|
6
6
|
import android.os.Handler;
|
|
7
7
|
import androidx.annotation.NonNull;
|
|
8
8
|
import androidx.appcompat.app.AppCompatActivity;
|
|
9
|
+
import androidx.biometric.BiometricManager;
|
|
9
10
|
import androidx.biometric.BiometricPrompt;
|
|
10
11
|
import ee.forgr.biometric.capacitornativebiometric.R;
|
|
12
|
+
import java.util.Objects;
|
|
11
13
|
import java.util.concurrent.Executor;
|
|
12
14
|
|
|
13
15
|
public class AuthActivity extends AppCompatActivity {
|
|
14
16
|
|
|
15
|
-
private Executor executor;
|
|
16
17
|
private int maxAttempts;
|
|
17
18
|
private int counter = 0;
|
|
18
19
|
|
|
@@ -23,6 +24,7 @@ public class AuthActivity extends AppCompatActivity {
|
|
|
23
24
|
|
|
24
25
|
maxAttempts = getIntent().getIntExtra("maxAttempts", 1);
|
|
25
26
|
|
|
27
|
+
Executor executor;
|
|
26
28
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
|
|
27
29
|
executor = this.getMainExecutor();
|
|
28
30
|
} else {
|
|
@@ -38,7 +40,7 @@ public class AuthActivity extends AppCompatActivity {
|
|
|
38
40
|
new BiometricPrompt.PromptInfo.Builder()
|
|
39
41
|
.setTitle(
|
|
40
42
|
getIntent().hasExtra("title")
|
|
41
|
-
? getIntent().getStringExtra("title")
|
|
43
|
+
? Objects.requireNonNull(getIntent().getStringExtra("title"))
|
|
42
44
|
: "Authenticate"
|
|
43
45
|
)
|
|
44
46
|
.setSubtitle(
|
|
@@ -53,18 +55,30 @@ public class AuthActivity extends AppCompatActivity {
|
|
|
53
55
|
);
|
|
54
56
|
|
|
55
57
|
boolean useFallback = getIntent().getBooleanExtra("useFallback", false);
|
|
58
|
+
int[] allowedTypes = getIntent().getIntArrayExtra("allowedBiometryTypes");
|
|
56
59
|
|
|
57
|
-
if (
|
|
58
|
-
|
|
59
|
-
|
|
60
|
+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
|
|
61
|
+
int authenticators = BiometricManager.Authenticators.BIOMETRIC_STRONG;
|
|
62
|
+
if (useFallback) {
|
|
63
|
+
authenticators |= BiometricManager.Authenticators.DEVICE_CREDENTIAL;
|
|
64
|
+
}
|
|
65
|
+
if (allowedTypes != null) {
|
|
66
|
+
// Filter authenticators based on allowed types
|
|
67
|
+
authenticators = getAllowedAuthenticators(allowedTypes);
|
|
68
|
+
}
|
|
69
|
+
builder.setAllowedAuthenticators(authenticators);
|
|
60
70
|
} else {
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
71
|
+
if (useFallback) {
|
|
72
|
+
builder.setDeviceCredentialAllowed(true);
|
|
73
|
+
} else {
|
|
74
|
+
builder.setNegativeButtonText(
|
|
75
|
+
getIntent().hasExtra("negativeButtonText")
|
|
76
|
+
? Objects.requireNonNull(
|
|
77
|
+
getIntent().getStringExtra("negativeButtonText")
|
|
78
|
+
)
|
|
79
|
+
: "Cancel"
|
|
80
|
+
);
|
|
81
|
+
}
|
|
68
82
|
}
|
|
69
83
|
|
|
70
84
|
BiometricPrompt.PromptInfo promptInfo = builder.build();
|
|
@@ -90,7 +104,7 @@ public class AuthActivity extends AppCompatActivity {
|
|
|
90
104
|
@NonNull BiometricPrompt.AuthenticationResult result
|
|
91
105
|
) {
|
|
92
106
|
super.onAuthenticationSucceeded(result);
|
|
93
|
-
finishActivity(
|
|
107
|
+
finishActivity();
|
|
94
108
|
}
|
|
95
109
|
|
|
96
110
|
@Override
|
|
@@ -109,8 +123,8 @@ public class AuthActivity extends AppCompatActivity {
|
|
|
109
123
|
biometricPrompt.authenticate(promptInfo);
|
|
110
124
|
}
|
|
111
125
|
|
|
112
|
-
void finishActivity(
|
|
113
|
-
finishActivity(
|
|
126
|
+
void finishActivity() {
|
|
127
|
+
finishActivity("success", null, null);
|
|
114
128
|
}
|
|
115
129
|
|
|
116
130
|
void finishActivity(String result, Integer errorCode, String errorDetails) {
|
|
@@ -158,4 +172,24 @@ public class AuthActivity extends AppCompatActivity {
|
|
|
158
172
|
return 0;
|
|
159
173
|
}
|
|
160
174
|
}
|
|
175
|
+
|
|
176
|
+
private int getAllowedAuthenticators(int[] allowedTypes) {
|
|
177
|
+
int authenticators = 0;
|
|
178
|
+
for (int type : allowedTypes) {
|
|
179
|
+
switch (type) {
|
|
180
|
+
case 3: // FINGERPRINT
|
|
181
|
+
authenticators |= BiometricManager.Authenticators.BIOMETRIC_STRONG;
|
|
182
|
+
break;
|
|
183
|
+
case 4: // FACE_AUTHENTICATION
|
|
184
|
+
authenticators |= BiometricManager.Authenticators.BIOMETRIC_STRONG;
|
|
185
|
+
break;
|
|
186
|
+
case 5: // IRIS_AUTHENTICATION
|
|
187
|
+
authenticators |= BiometricManager.Authenticators.BIOMETRIC_STRONG;
|
|
188
|
+
break;
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
return authenticators > 0
|
|
192
|
+
? authenticators
|
|
193
|
+
: BiometricManager.Authenticators.BIOMETRIC_STRONG;
|
|
194
|
+
}
|
|
161
195
|
}
|
|
@@ -15,6 +15,7 @@ import android.security.keystore.StrongBoxUnavailableException;
|
|
|
15
15
|
import android.util.Base64;
|
|
16
16
|
import androidx.activity.result.ActivityResult;
|
|
17
17
|
import androidx.biometric.BiometricManager;
|
|
18
|
+
import com.getcapacitor.JSArray;
|
|
18
19
|
import com.getcapacitor.JSObject;
|
|
19
20
|
import com.getcapacitor.Plugin;
|
|
20
21
|
import com.getcapacitor.PluginCall;
|
|
@@ -24,6 +25,7 @@ import com.getcapacitor.annotation.CapacitorPlugin;
|
|
|
24
25
|
import java.io.ByteArrayInputStream;
|
|
25
26
|
import java.io.ByteArrayOutputStream;
|
|
26
27
|
import java.io.IOException;
|
|
28
|
+
import java.nio.charset.StandardCharsets;
|
|
27
29
|
import java.security.GeneralSecurityException;
|
|
28
30
|
import java.security.InvalidAlgorithmParameterException;
|
|
29
31
|
import java.security.InvalidKeyException;
|
|
@@ -37,6 +39,7 @@ import java.security.SecureRandom;
|
|
|
37
39
|
import java.security.UnrecoverableEntryException;
|
|
38
40
|
import java.security.cert.CertificateException;
|
|
39
41
|
import java.util.ArrayList;
|
|
42
|
+
import java.util.Objects;
|
|
40
43
|
import javax.crypto.Cipher;
|
|
41
44
|
import javax.crypto.CipherInputStream;
|
|
42
45
|
import javax.crypto.CipherOutputStream;
|
|
@@ -44,6 +47,7 @@ import javax.crypto.KeyGenerator;
|
|
|
44
47
|
import javax.crypto.NoSuchPaddingException;
|
|
45
48
|
import javax.crypto.spec.GCMParameterSpec;
|
|
46
49
|
import javax.crypto.spec.SecretKeySpec;
|
|
50
|
+
import org.json.JSONException;
|
|
47
51
|
|
|
48
52
|
@CapacitorPlugin(name = "NativeBiometric")
|
|
49
53
|
public class NativeBiometric extends Plugin {
|
|
@@ -144,7 +148,7 @@ public class NativeBiometric extends Plugin {
|
|
|
144
148
|
}
|
|
145
149
|
|
|
146
150
|
@PluginMethod
|
|
147
|
-
public void verifyIdentity(final PluginCall call) {
|
|
151
|
+
public void verifyIdentity(final PluginCall call) throws JSONException {
|
|
148
152
|
Intent intent = new Intent(getContext(), AuthActivity.class);
|
|
149
153
|
|
|
150
154
|
intent.putExtra("title", call.getString("title", "Authenticate"));
|
|
@@ -168,6 +172,16 @@ public class NativeBiometric extends Plugin {
|
|
|
168
172
|
intent.putExtra("maxAttempts", call.getInt("maxAttempts"));
|
|
169
173
|
}
|
|
170
174
|
|
|
175
|
+
// Pass allowed biometry types
|
|
176
|
+
JSArray allowedTypes = call.getArray("allowedBiometryTypes");
|
|
177
|
+
if (allowedTypes != null) {
|
|
178
|
+
int[] types = new int[allowedTypes.length()];
|
|
179
|
+
for (int i = 0; i < allowedTypes.length(); i++) {
|
|
180
|
+
types[i] = (int) allowedTypes.toList().get(i);
|
|
181
|
+
}
|
|
182
|
+
intent.putExtra("allowedBiometryTypes", types);
|
|
183
|
+
}
|
|
184
|
+
|
|
171
185
|
boolean useFallback = Boolean.TRUE.equals(
|
|
172
186
|
call.getBoolean("useFallback", false)
|
|
173
187
|
);
|
|
@@ -255,7 +269,7 @@ public class NativeBiometric extends Plugin {
|
|
|
255
269
|
if (result.getResultCode() == Activity.RESULT_OK) {
|
|
256
270
|
Intent data = result.getData();
|
|
257
271
|
if (data != null && data.hasExtra("result")) {
|
|
258
|
-
switch (data.getStringExtra("result")) {
|
|
272
|
+
switch (Objects.requireNonNull(data.getStringExtra("result"))) {
|
|
259
273
|
case "success":
|
|
260
274
|
call.resolve();
|
|
261
275
|
break;
|
|
@@ -309,18 +323,15 @@ public class NativeBiometric extends Plugin {
|
|
|
309
323
|
private String encryptString(String stringToEncrypt, String KEY_ALIAS)
|
|
310
324
|
throws GeneralSecurityException, IOException {
|
|
311
325
|
Cipher cipher;
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
cipher.init(Cipher.ENCRYPT_MODE, getKey(KEY_ALIAS));
|
|
322
|
-
}
|
|
323
|
-
byte[] encodedBytes = cipher.doFinal(stringToEncrypt.getBytes("UTF-8"));
|
|
326
|
+
cipher = Cipher.getInstance(TRANSFORMATION);
|
|
327
|
+
cipher.init(
|
|
328
|
+
Cipher.ENCRYPT_MODE,
|
|
329
|
+
getKey(KEY_ALIAS),
|
|
330
|
+
new GCMParameterSpec(128, FIXED_IV)
|
|
331
|
+
);
|
|
332
|
+
byte[] encodedBytes = cipher.doFinal(
|
|
333
|
+
stringToEncrypt.getBytes(StandardCharsets.UTF_8)
|
|
334
|
+
);
|
|
324
335
|
return Base64.encodeToString(encodedBytes, Base64.DEFAULT);
|
|
325
336
|
}
|
|
326
337
|
|
|
@@ -329,19 +340,14 @@ public class NativeBiometric extends Plugin {
|
|
|
329
340
|
byte[] encryptedData = Base64.decode(stringToDecrypt, Base64.DEFAULT);
|
|
330
341
|
|
|
331
342
|
Cipher cipher;
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
);
|
|
339
|
-
} else {
|
|
340
|
-
cipher = Cipher.getInstance(AES_MODE, "BC");
|
|
341
|
-
cipher.init(Cipher.DECRYPT_MODE, getKey(KEY_ALIAS));
|
|
342
|
-
}
|
|
343
|
+
cipher = Cipher.getInstance(TRANSFORMATION);
|
|
344
|
+
cipher.init(
|
|
345
|
+
Cipher.DECRYPT_MODE,
|
|
346
|
+
getKey(KEY_ALIAS),
|
|
347
|
+
new GCMParameterSpec(128, FIXED_IV)
|
|
348
|
+
);
|
|
343
349
|
byte[] decryptedData = cipher.doFinal(encryptedData);
|
|
344
|
-
return new String(decryptedData,
|
|
350
|
+
return new String(decryptedData, StandardCharsets.UTF_8);
|
|
345
351
|
}
|
|
346
352
|
|
|
347
353
|
@SuppressLint("NewAPI") // API level is already checked
|
|
@@ -358,30 +364,31 @@ public class NativeBiometric extends Plugin {
|
|
|
358
364
|
|
|
359
365
|
private Key generateKey(String KEY_ALIAS, boolean isStrongBoxBacked)
|
|
360
366
|
throws GeneralSecurityException, IOException, StrongBoxUnavailableException {
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
367
|
+
KeyGenerator generator = KeyGenerator.getInstance(
|
|
368
|
+
KeyProperties.KEY_ALGORITHM_AES,
|
|
369
|
+
ANDROID_KEY_STORE
|
|
370
|
+
);
|
|
371
|
+
KeyGenParameterSpec.Builder paramBuilder = new KeyGenParameterSpec.Builder(
|
|
372
|
+
KEY_ALIAS,
|
|
373
|
+
KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT
|
|
374
|
+
)
|
|
375
|
+
.setBlockModes(KeyProperties.BLOCK_MODE_GCM)
|
|
376
|
+
.setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE)
|
|
377
|
+
.setRandomizedEncryptionRequired(false);
|
|
378
|
+
|
|
379
|
+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
|
|
380
|
+
if (
|
|
381
|
+
Build.VERSION.SDK_INT < Build.VERSION_CODES.S ||
|
|
382
|
+
Build.VERSION.SDK_INT > 34
|
|
383
|
+
) {
|
|
384
|
+
// Avoiding setUnlockedDeviceRequired(true) due to known issues on Android 12-14
|
|
376
385
|
paramBuilder.setUnlockedDeviceRequired(true);
|
|
377
|
-
paramBuilder.setIsStrongBoxBacked(isStrongBoxBacked);
|
|
378
386
|
}
|
|
379
|
-
|
|
380
|
-
generator.init(paramBuilder.build());
|
|
381
|
-
return generator.generateKey();
|
|
382
|
-
} else {
|
|
383
|
-
return getAESKey(KEY_ALIAS);
|
|
387
|
+
paramBuilder.setIsStrongBoxBacked(isStrongBoxBacked);
|
|
384
388
|
}
|
|
389
|
+
|
|
390
|
+
generator.init(paramBuilder.build());
|
|
391
|
+
return generator.generateKey();
|
|
385
392
|
}
|
|
386
393
|
|
|
387
394
|
private Key getKey(String KEY_ALIAS)
|
|
@@ -485,7 +492,7 @@ public class NativeBiometric extends Plugin {
|
|
|
485
492
|
|
|
486
493
|
byte[] bytes = new byte[values.size()];
|
|
487
494
|
for (int i = 0; i < bytes.length; i++) {
|
|
488
|
-
bytes[i] = values.get(i)
|
|
495
|
+
bytes[i] = values.get(i);
|
|
489
496
|
}
|
|
490
497
|
return bytes;
|
|
491
498
|
}
|
|
@@ -494,10 +501,6 @@ public class NativeBiometric extends Plugin {
|
|
|
494
501
|
KeyguardManager keyguardManager = (KeyguardManager) getActivity()
|
|
495
502
|
.getSystemService(Context.KEYGUARD_SERVICE);
|
|
496
503
|
// Can only use fallback if the device has a pin/pattern/password lockscreen.
|
|
497
|
-
|
|
498
|
-
return keyguardManager.isDeviceSecure();
|
|
499
|
-
} else {
|
|
500
|
-
return keyguardManager.isKeyguardSecure();
|
|
501
|
-
}
|
|
504
|
+
return keyguardManager.isDeviceSecure();
|
|
502
505
|
}
|
|
503
506
|
}
|