@aparajita/capacitor-biometric-auth 2.0.7 β†’ 3.0.1

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.
@@ -12,7 +12,7 @@
12
12
  s.author = package['author']
13
13
  s.source = { :git => package['repository']['url'], :tag => s.version.to_s }
14
14
  s.source_files = 'ios/Plugin/**/*.{swift,h,m,c,cc,mm,cpp}'
15
- s.ios.deployment_target = '12.0'
15
+ s.ios.deployment_target = '13.0'
16
16
  s.dependency 'Capacitor'
17
17
  s.swift_version = '5.1'
18
18
  end
package/README.md CHANGED
@@ -2,19 +2,19 @@
2
2
 
3
3
  # capacitor-biometric-auth  [![npm version](https://badge.fury.io/js/@aparajita%2Fcapacitor-biometric-auth.svg)](https://badge.fury.io/js/@aparajita%2Fcapacitor-biometric-auth)
4
4
 
5
- This plugin for [Capacitor 3](https://capacitorjs.com) provides access to native biometry on iOS and Android. It supports every type of biometry and every configuration option on both platforms. In addition, biometry is simulated on the web so you can test your logic without making any changes to your code.
5
+ This plugin for [Capacitor 4](https://capacitorjs.com) provides access to native biometry on iOS and Android. It supports every type of biometry and every configuration option on both platforms. In addition, biometry is simulated on the web so you can test your logic without making any changes to your code.
6
6
 
7
- πŸ‘‰ **NOTE:** This plugin only works with Capacitor 3. If you are upgrading from the Capacitor 2 version, note that the plugin name has changed to `BiometricAuth`.
7
+ πŸ‘‰ **NOTE:** This plugin only works with Capacitor 4. If you are upgrading from the Capacitor 2 version, note that the plugin name has changed to `BiometricAuth`.
8
8
 
9
- πŸ›‘ **IMPORTANT:** If you are upgrading from a version prior to 2.0.5, please note that `androidMaxAttempts` in [`AuthenticateOptions`](#authenticateoptions) is now the maximum consecutive failed attempts that are allowed, vs. the previous behavior which was maximum consecutive failed attempts + 1 (which was a bug). So if `androidMaxAttempts` is set to 3, [`authenticate`](#authenticate) will return `BiometryErrorType.authenticationFailed`as soon as the third consecutive attempt fails.
9
+ πŸ›‘ **BREAKING CHANGE:** If you are upgrading from a version prior to 3.0.0, please note that `androidMaxAttempts` is no longer supported. See the documentation for [`authenticate()`](#authenticate) for more information.
10
10
 
11
11
  ## Demos
12
12
 
13
13
  Here is `capacitor-biometric-auth` running on the [demo app](https://github.com/aparajita/capacitor-biometric-auth-demo) on both iOS and Android.
14
14
 
15
- |iOS|Android|
16
- |---|-------|
17
- |<video src="https://user-images.githubusercontent.com/22218/177023147-1f9abce4-2dc3-4157-8bf1-d8d9fdba3977.mp4" width="352" />|<video src="https://user-images.githubusercontent.com/22218/177023168-d7c18a4b-a2f9-49f9-ae39-40884219c128.mp4" width="365" />|
15
+ | iOS | Android |
16
+ | :----------------------------------------------------------------------------------------------------------------------------- | :----------------------------------------------------------------------------------------------------------------------------- |
17
+ | <video src="https://user-images.githubusercontent.com/22218/182895212-5f7bfa39-6db1-4149-859b-85cff7012903.mp4" width="352" /> | <video src="https://user-images.githubusercontent.com/22218/182898192-d16243b8-3671-4c32-9e25-5e37feeb43d4.mp4" width="365" /> |
18
18
 
19
19
  ## Installation
20
20
 
@@ -22,7 +22,7 @@ Here is `capacitor-biometric-auth` running on the [demo app](https://github.com/
22
22
  pnpm add @aparajita/capacitor-biometric-auth
23
23
  ```
24
24
 
25
- Not using [pnpm](https://pnpm.js.org/)? You owe it to yourself to give it a try. It’s faster, better with monorepos, and uses *way, way* less disk space than the alternatives.
25
+ Not using [pnpm](https://pnpm.js.org/)? You owe it to yourself to give it a try. It’s faster, better with monorepos, and uses _way, way_ less disk space than the alternatives.
26
26
 
27
27
  ## Usage
28
28
 
@@ -30,7 +30,7 @@ The API is extensively documented in the [TypeScript definitions file](src/defin
30
30
 
31
31
  ### Checking availability
32
32
 
33
- Before giving the user the option to use biometry (such as displaying a biometry icon), call [`checkBiometry`](#checkbiometry) and inspect the [`CheckBiometryResult`](#checkbiometryresult) to see what (if any) biometry is available on the device. Note that `isAvailable` may be `false` but `biometryType` may indicate the presence of biometry on the device. This occurs if the current user is not enrolled in biometry, or if biometry has been disabled for the current app. In such cases the `reason` will tell you why.
33
+ Before giving the user the option to use biometry (such as displaying a biometry icon), call [`checkBiometry`](#checkbiometry) and inspect the [`CheckBiometryResult`](#checkbiometryresult) to see what (if any) biometry is available on the device. Note that `isAvailable` may be `false` but `biometryType` may indicate the presence of biometry on the device. This occurs if the current user is not enrolled in biometry, or if biometry has been disabled for the current app. In such cases the `reason` will tell you why.
34
34
 
35
35
  Because the availability of biometry can change while your app is in the background, it’s important to check availability when your app resumes. By calling [`addResumeListener`](#addresumelistener) you can register a callback that is passed a [`CheckBiometryResult`](#checkbiometryresult) when your app resumes.
36
36
 
@@ -40,10 +40,10 @@ Once you have determined that biometry is available, to initiate biometric authe
40
40
 
41
41
  If authentication succeeds, the Promise resolves. If authentication fails, the Promise is rejected with a `BiometryError`, which has two properties:
42
42
 
43
- | Property | Type | Description |
44
- | :---------- |:--------------------------------------------------------------------------------------------------------| :------------- |
45
- | message | string | A description of the error suitable for debugging |
46
- | code | [BiometryErrorType](https://github.com/aparajita/capacitor-biometric-auth/blob/main/src/definitions.ts) | What caused the error |
43
+ | Property | Type | Description |
44
+ | :------- | :------------------------------------------------------------------------------------------------------ | :------------------------------------------------ |
45
+ | message | string | A description of the error suitable for debugging |
46
+ | code | [BiometryErrorType](https://github.com/aparajita/capacitor-biometric-auth/blob/main/src/definitions.ts) | What caused the error |
47
47
 
48
48
  ## Biometry support
49
49
 
@@ -60,16 +60,16 @@ On iOS, Touch ID and Face ID are supported.
60
60
  On Android, fingerprint, face, and iris authentication are supported. Note that if a device supports more than one type of biometry, the plugin will only present the primary type, which is determined by the system.
61
61
 
62
62
  ## API
63
- <docgen-index>
64
63
 
65
- [checkBiometry()](#checkbiometry)
66
- [setBiometryType(...)](#setbiometrytype)
67
- [authenticate(...)](#authenticate)
68
- [addResumeListener(...)](#addresumelistener)
64
+ <docgen-index>
69
65
 
70
- [Interfaces](#interfaces)
71
- [Type Aliases](#type-aliases)
72
- [Enums](#enums)
66
+ - [`checkBiometry()`](#checkbiometry)
67
+ - [`setBiometryType(...)`](#setbiometrytype)
68
+ - [`authenticate(...)`](#authenticate)
69
+ - [`addResumeListener(...)`](#addresumelistener)
70
+ - [Interfaces](#interfaces)
71
+ - [Type Aliases](#type-aliases)
72
+ - [Enums](#enums)
73
73
 
74
74
  </docgen-index>
75
75
  <docgen-api>
@@ -85,8 +85,7 @@ Check to see what biometry type (if any) is available.
85
85
 
86
86
  **Returns:** Promise&lt;<a href="#checkbiometryresult">CheckBiometryResult</a>&gt;
87
87
 
88
- --------------------
89
-
88
+ ---
90
89
 
91
90
  ### setBiometryType(...)
92
91
 
@@ -96,12 +95,11 @@ setBiometryType(type: BiometryType | string | undefined) => void
96
95
 
97
96
  web only<br><br>On the web, this method allows you to dynamically simulate different types of biometry. You may either pass a <a href="#biometrytype">`BiometryType`</a> enum or the string name of a <a href="#biometrytype">`BiometryType`</a>. If a string is passed and it isn't a valid value, nothing happens.
98
97
 
99
- | Param | Type |
100
- | :---------- | :--------------------------------------------------------------- |
101
- |type|string \| <a href="#biometrytype">BiometryType</a>|
102
-
103
- --------------------
98
+ | Param | Type |
99
+ | :---- | :------------------------------------------------- |
100
+ | type | string \| <a href="#biometrytype">BiometryType</a> |
104
101
 
102
+ ---
105
103
 
106
104
  ### authenticate(...)
107
105
 
@@ -109,14 +107,13 @@ web only<br><br>On the web, this method allows you to dynamically simulate diffe
109
107
  authenticate(options?: AuthenticateOptions) => Promise<void>
110
108
  ```
111
109
 
112
- Prompt the user for authentication. If authorization fails for any reason, the promise is rejected with a `BiometryError`.
110
+ Prompt the user for authentication. If authorization fails for any reason, the promise is rejected with a `BiometryError`.<br><br>For detailed information about the behavior on iOS, see:<br><br>https://developer.apple.com/documentation/localauthentication/lapolicy/deviceownerauthenticationwithbiometrics<br><br>Android imposes a limit of 5 failed attempts. If `allowDeviceCredential` is `true`, the user will then be presented with a device credential prompt. If `allowDeviceCredential` is `false`, `authenticate()` will reject with a `BiometryErrorType` of `biometryLockout`, after which the user will have to wait 30 seconds before being allowed to authenticate again.
113
111
 
114
- | Param | Type |
115
- | :------------- | :------------------------------------------------------------------- |
116
- |options|<a href="#authenticateoptions">AuthenticateOptions</a>|
117
-
118
- --------------------
112
+ | Param | Type |
113
+ | :------ | :----------------------------------------------------- |
114
+ | options | <a href="#authenticateoptions">AuthenticateOptions</a> |
119
115
 
116
+ ---
120
117
 
121
118
  ### addResumeListener(...)
122
119
 
@@ -126,70 +123,61 @@ addResumeListener(listener: ResumeListener) => Promise<PluginListenerHandle>
126
123
 
127
124
  Register a function that will be called when the app resumes. The function will be passed the result of `checkBiometry()`.
128
125
 
129
- | Param | Type |
130
- | :-------------- | :--------------------------------------------------------- |
131
- |listener|<a href="#resumelistener">ResumeListener</a>|
126
+ | Param | Type |
127
+ | :------- | :------------------------------------------- |
128
+ | listener | <a href="#resumelistener">ResumeListener</a> |
132
129
 
133
130
  **Returns:** Promise&lt;<a href="#pluginlistenerhandle">PluginListenerHandle</a>&gt;
134
131
 
135
- --------------------
136
-
132
+ ---
137
133
 
138
134
  ### Interfaces
139
135
 
140
-
141
136
  #### CheckBiometryResult
142
137
 
143
- | Prop | Type | Description |
144
- | :------------------ | :----------------------------------------------------- | :------------------------------------------------------------------------------------------------------------------------- |
145
- |isAvailable|boolean| True if the device has biometric authentication capability and the current user has enrolled in biometry. |
146
- |biometryType|<a href="#biometrytype">BiometryType</a>| The type of biometry available on the device. |
147
- |reason|string| If biometry is not available and the system gives a reason why, it will be returned here. Otherwise it's an empty string. |
148
-
138
+ | Prop | Type | Description |
139
+ | :----------- | :--------------------------------------- | :------------------------------------------------------------------------------------------------------------------------ |
140
+ | isAvailable | boolean | True if the device has biometric authentication capability and the current user has enrolled in biometry. |
141
+ | biometryType | <a href="#biometrytype">BiometryType</a> | The type of biometry available on the device. |
142
+ | reason | string | If biometry is not available and the system gives a reason why, it will be returned here. Otherwise it's an empty string. |
149
143
 
150
144
  #### AuthenticateOptions
151
145
 
152
- | Prop | Type | Description |
153
- | :--------------------------- | :-------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
154
- |reason|string| The reason for requesting authentication. Displays in the authentication dialog presented to the user. If not supplied, a default message is displayed. |
155
- |cancelTitle|string| iOS: The system presents a cancel button during biometric authentication to let the user abort the authentication attempt. The button appears every time the system asks the user to present a finger registered with Touch ID. For Face ID, the button only appears if authentication fails and the user is prompted to try again. Either way, the user can stop trying to authenticate by tapping the button.<br><br>Android: The text for the negative button. This would typically be used as a "Cancel" button, but may be also used to show an alternative method for authentication, such as a screen that asks for a backup password.<br><br>Default: "Cancel" |
156
- |allowDeviceCredential|boolean| If true, allows for authentication using device unlock credentials. Default is false.<br><br>iOS: If biometry is available, enrolled, and not disabled, the system uses that first. After the first Touch ID failure or second Face ID failure, if `iosFallbackTitle` is not an empty string, a fallback button appears in the authentication dialog. If the user taps the fallback button, the system prompts the user for the device passcode or the user’s password. If `iosFallbackTitle` is an empty string, no fallback button will appear.<br><br>If biometry is not available, enrolled and enabled, and a passcode is set, the system immediately prompts the user for the device passcode or user’s password. Authentication fails with the error code `passcodeNotSet` if the device passcode isn’t enabled.<br><br>If a passcode is not set on the device, a `passcodeNotSet` error is returned.<br><br>The system disables passcode authentication after 6 unsuccessful attempts, with progressively increasing delays between attempts.<br><br>The title of the fallback button may be customized by setting `iosFallbackTitle` to a non-empty string.<br><br>Android: The user will first be prompted to authenticate with biometrics, but also given the option to authenticate with their device PIN, pattern, or password by tapping a button in the authentication dialog. The title of the button is supplied by the system. |
157
- |iosFallbackTitle|string| The system presents a fallback button when biometric authentication fails β€” for example, because the system doesn’t recognize the presented finger, or after several failed attempts to recognize the user’s face.<br><br>If `allowDeviceCredential` is false, tapping this button dismisses the authentication dialog and returns the error code userFallback. If undefined, the localized systetm default title is used. Passing an empty string hides the fallback button completely.<br><br>If `allowDeviceCredential` is true and this is undefined, the localized system default title is used. |
158
- |androidTitle|string| Title for the Android dialog. If not supplied, the system default is used. |
159
- |androidSubtitle|string| Subtitle for the Android dialog. If not supplied, the system default is used. |
160
- |androidMaxAttempts|number| When this many consecutive biometric verification attempts fail, `authenticate` returns `BiometryErrorType.authenticationFailed`. The default is 3. |
161
-
146
+ | Prop | Type | Description |
147
+ | :-------------------- | :------ | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
148
+ | reason | string | The reason for requesting authentication. Displays in the authentication dialog presented to the user. If not supplied, a default message is displayed. |
149
+ | cancelTitle | string | iOS: The system presents a cancel button during biometric authentication to let the user abort the authentication attempt. The button appears every time the system asks the user to present a finger registered with Touch ID. For Face ID, the button only appears if authentication fails and the user is prompted to try again. Either way, the user can stop trying to authenticate by tapping the button.<br><br>Android: The text for the negative button. This would typically be used as a "Cancel" button, but may be also used to show an alternative method for authentication, such as a screen that asks for a backup password.<br><br>Default: "Cancel" |
150
+ | allowDeviceCredential | boolean | If true, allows for authentication using device unlock credentials. Default is false.<br><br>iOS: If biometry is available, enrolled, and not disabled, the system uses that first. After the first Touch ID failure or second Face ID failure, if `iosFallbackTitle` is not an empty string, a fallback button appears in the authentication dialog. If the user taps the fallback button, the system prompts the user for the device passcode or the user’s password. If `iosFallbackTitle` is an empty string, no fallback button will appear.<br><br>If biometry is not available, enrolled and enabled, and a passcode is set, the system immediately prompts the user for the device passcode or user’s password. Authentication fails with the error code `passcodeNotSet` if the device passcode isn’t enabled.<br><br>If a passcode is not set on the device, a `passcodeNotSet` error is returned.<br><br>The system disables passcode authentication after 6 unsuccessful attempts, with progressively increasing delays between attempts.<br><br>The title of the fallback button may be customized by setting `iosFallbackTitle` to a non-empty string.<br><br>Android: The user will first be prompted to authenticate with biometrics, but also given the option to authenticate with their device PIN, pattern, or password by tapping a button in the authentication dialog. The title of the button is supplied by the system. |
151
+ | iosFallbackTitle | string | The system presents a fallback button when biometric authentication fails β€” for example, because the system doesn’t recognize the presented finger, or after several failed attempts to recognize the user’s face.<br><br>If `allowDeviceCredential` is false, tapping this button dismisses the authentication dialog and returns the error code userFallback. If undefined, the localized systetm default title is used. Passing an empty string hides the fallback button completely.<br><br>If `allowDeviceCredential` is true and this is undefined, the localized system default title is used. |
152
+ | androidTitle | string | Title for the Android dialog. If not supplied, the system default is used. |
153
+ | androidSubtitle | string | Subtitle for the Android dialog. If not supplied, the system default is used. |
162
154
 
163
155
  #### PluginListenerHandle
164
156
 
165
157
  | Method | Signature |
166
- | :---------- | :---------------------------- |
158
+ | :--------- | :--------------------------- |
167
159
  | **remove** | () =&gt; Promise&lt;void&gt; |
168
160
 
169
-
170
161
  ### Type Aliases
171
162
 
172
-
173
163
  #### ResumeListener
174
164
 
175
165
  The signature of the callback passed to `addResumeListener()`.
176
166
 
177
167
  <code>(info: <a href="#checkbiometryresult">CheckBiometryResult</a>): void</code>
178
168
 
179
-
180
169
  ### Enums
181
170
 
182
-
183
171
  #### BiometryType
184
172
 
185
- | Members | Description |
186
- | :------------------------------- | :----------------------------------------------- |
187
- |none| No biometry is available |
188
- |touchId| iOS Touch ID is available |
189
- |faceId| iOS Face ID is available |
190
- |fingerprintAuthentication| Android fingerprint authentication is available |
191
- |faceAuthentication| Android face authentication is available |
192
- |irisAuthentication| Android iris authentication is available |
173
+ | Members | Description |
174
+ | :------------------------ | :---------------------------------------------- |
175
+ | none | No biometry is available |
176
+ | touchId | iOS Touch ID is available |
177
+ | faceId | iOS Face ID is available |
178
+ | fingerprintAuthentication | Android fingerprint authentication is available |
179
+ | faceAuthentication | Android face authentication is available |
180
+ | irisAuthentication | Android iris authentication is available |
193
181
 
194
182
  </docgen-api>
195
183
  </div>
@@ -1,26 +1,26 @@
1
1
  ext {
2
- junitVersion = project.hasProperty('junitVersion') ? rootProject.ext.junitVersion : '4.12'
3
- androidxJunitVersion = project.hasProperty('androidxJunitVersion') ? rootProject.ext.androidxJunitVersion : '1.1.1'
4
- androidxEspressoCoreVersion = project.hasProperty('androidxEspressoCoreVersion') ? rootProject.ext.androidxEspressoCoreVersion : '3.2.0'
2
+ junitVersion = project.hasProperty('junitVersion') ? rootProject.ext.junitVersion : '4.13.2'
3
+ androidxJunitVersion = project.hasProperty('androidxJunitVersion') ? rootProject.ext.androidxJunitVersion : '1.1.3'
4
+ androidxEspressoCoreVersion = project.hasProperty('androidxEspressoCoreVersion') ? rootProject.ext.androidxEspressoCoreVersion : '3.4.0'
5
5
  }
6
6
 
7
7
  buildscript {
8
8
  repositories {
9
9
  google()
10
- jcenter()
10
+ mavenCentral()
11
11
  }
12
12
  dependencies {
13
- classpath 'com.android.tools.build:gradle:4.1.1'
13
+ classpath 'com.android.tools.build:gradle:4.1.3'
14
14
  }
15
15
  }
16
16
 
17
17
  apply plugin: 'com.android.library'
18
18
 
19
19
  android {
20
- compileSdkVersion project.hasProperty('compileSdkVersion') ? rootProject.ext.compileSdkVersion : 30
20
+ compileSdkVersion project.hasProperty('compileSdkVersion') ? rootProject.ext.compileSdkVersion : 32
21
21
  defaultConfig {
22
- minSdkVersion project.hasProperty('minSdkVersion') ? rootProject.ext.minSdkVersion : 21
23
- targetSdkVersion project.hasProperty('targetSdkVersion') ? rootProject.ext.targetSdkVersion : 30
22
+ minSdkVersion project.hasProperty('minSdkVersion') ? rootProject.ext.minSdkVersion : 22
23
+ targetSdkVersion project.hasProperty('targetSdkVersion') ? rootProject.ext.targetSdkVersion : 32
24
24
  versionCode 1
25
25
  versionName "1.0"
26
26
  testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
@@ -35,27 +35,26 @@ android {
35
35
  abortOnError false
36
36
  }
37
37
  compileOptions {
38
- sourceCompatibility JavaVersion.VERSION_1_8
39
- targetCompatibility JavaVersion.VERSION_1_8
38
+ sourceCompatibility JavaVersion.VERSION_11
39
+ targetCompatibility JavaVersion.VERSION_11
40
40
  }
41
41
  }
42
42
 
43
43
  repositories {
44
44
  google()
45
- jcenter()
46
45
  mavenCentral()
47
46
  }
48
47
 
49
48
 
50
49
  dependencies {
51
- implementation 'androidx.biometric:biometric:1.0.1'
50
+ implementation 'androidx.biometric:biometric:1.1.0'
52
51
  implementation fileTree(dir: 'libs', include: ['*.jar'])
53
52
  implementation project(':capacitor-android')
54
- implementation 'androidx.appcompat:appcompat:1.1.0'
55
- implementation 'com.google.android.material:material:1.1.0'
56
- implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
57
- implementation 'androidx.navigation:navigation-fragment:2.0.0'
58
- implementation 'androidx.navigation:navigation-ui:2.0.0'
53
+ implementation 'androidx.appcompat:appcompat:1.4.2'
54
+ implementation 'com.google.android.material:material:1.6.1'
55
+ implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
56
+ implementation 'androidx.navigation:navigation-fragment:2.5.1'
57
+ implementation 'androidx.navigation:navigation-ui:2.5.1'
59
58
  testImplementation "junit:junit:$junitVersion"
60
59
  androidTestImplementation "androidx.test.ext:junit:$androidxJunitVersion"
61
60
  androidTestImplementation "androidx.test.espresso:espresso-core:$androidxEspressoCoreVersion"
@@ -3,6 +3,7 @@ package com.aparajita.capacitor.biometricauth;
3
3
  import android.annotation.SuppressLint;
4
4
  import android.app.KeyguardManager;
5
5
  import android.content.Intent;
6
+ import android.hardware.biometrics.BiometricManager;
6
7
  import android.os.Build;
7
8
  import android.os.Bundle;
8
9
  import android.os.Handler;
@@ -13,9 +14,9 @@ import java.util.concurrent.Executor;
13
14
 
14
15
  public class AuthActivity extends AppCompatActivity {
15
16
 
16
- static int attemptCount;
17
17
  static boolean allowDeviceCredential;
18
18
 
19
+ @SuppressLint("WrongConstant")
19
20
  @Override
20
21
  protected void onCreate(Bundle savedInstanceState) {
21
22
  super.onCreate(savedInstanceState);
@@ -57,10 +58,21 @@ public class AuthActivity extends AppCompatActivity {
57
58
  title = "Authenticate";
58
59
  }
59
60
 
60
- builder.setTitle(title);
61
- builder.setSubtitle(subtitle);
62
- builder.setDescription(description);
63
- builder.setDeviceCredentialAllowed(allowDeviceCredential);
61
+ builder.setTitle(title)
62
+ .setSubtitle(subtitle)
63
+ .setDescription(description);
64
+
65
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
66
+ int authenticators = BiometricManager.Authenticators.BIOMETRIC_WEAK;
67
+
68
+ if (allowDeviceCredential) {
69
+ authenticators |= BiometricManager.Authenticators.DEVICE_CREDENTIAL;
70
+ }
71
+
72
+ builder.setAllowedAuthenticators(authenticators);
73
+ } else {
74
+ builder.setDeviceCredentialAllowed(allowDeviceCredential);
75
+ }
64
76
 
65
77
  // Android docs say that negative button text should not be set if device credential is allowed
66
78
  if (!allowDeviceCredential) {
@@ -75,8 +87,6 @@ public class AuthActivity extends AppCompatActivity {
75
87
  }
76
88
 
77
89
  BiometricPrompt.PromptInfo promptInfo = builder.build();
78
- attemptCount = 0;
79
-
80
90
  BiometricPrompt prompt = new BiometricPrompt(
81
91
  this,
82
92
  executor,
@@ -101,26 +111,6 @@ public class AuthActivity extends AppCompatActivity {
101
111
  super.onAuthenticationSucceeded(result);
102
112
  finishActivity();
103
113
  }
104
-
105
- @SuppressLint("DefaultLocale")
106
- @Override
107
- public void onAuthenticationFailed() {
108
- super.onAuthenticationFailed();
109
- attemptCount += 1;
110
-
111
- // When allowDeviceCredential is true, I can't seem to force the prompt
112
- // to go away, so skip attempt counting.
113
- if (!allowDeviceCredential && attemptCount >= maxAttempts) {
114
- finishActivity(
115
- BiometryResultType.FAILURE,
116
- 0,
117
- String.format(
118
- "The user reached the maximum of %d attempt(s)",
119
- maxAttempts
120
- )
121
- );
122
- }
123
- }
124
114
  }
125
115
  );
126
116
 
@@ -4,6 +4,7 @@ import android.annotation.SuppressLint;
4
4
  import android.app.Activity;
5
5
  import android.content.Intent;
6
6
  import android.content.pm.PackageManager;
7
+ import android.os.Build;
7
8
  import androidx.activity.result.ActivityResult;
8
9
  import androidx.biometric.BiometricManager;
9
10
  import androidx.biometric.BiometricPrompt;
@@ -91,17 +92,22 @@ public class BiometricAuth extends Plugin {
91
92
  @PluginMethod
92
93
  public void checkBiometry(PluginCall call) {
93
94
  BiometricManager manager = BiometricManager.from(getContext());
95
+ int biometryResult;
94
96
 
95
- int result = manager.canAuthenticate();
97
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
98
+ biometryResult = manager.canAuthenticate(BiometricManager.Authenticators.BIOMETRIC_WEAK);
99
+ } else {
100
+ biometryResult = manager.canAuthenticate();
101
+ }
96
102
 
97
103
  JSObject ret = new JSObject();
98
- ret.put("isAvailable", result == BiometricManager.BIOMETRIC_SUCCESS);
104
+ ret.put("isAvailable", biometryResult == BiometricManager.BIOMETRIC_SUCCESS);
99
105
  biometryType = getDeviceBiometryType();
100
106
  ret.put("biometryType", biometryType.getType());
101
107
 
102
108
  String reason = "";
103
109
 
104
- switch (result) {
110
+ switch (biometryResult) {
105
111
  case BiometricManager.BIOMETRIC_SUCCESS:
106
112
  break;
107
113
  case BiometricManager.BIOMETRIC_ERROR_HW_UNAVAILABLE:
@@ -113,6 +119,15 @@ public class BiometricAuth extends Plugin {
113
119
  case BiometricManager.BIOMETRIC_ERROR_NO_HARDWARE:
114
120
  reason = "There is no biometric hardware on this device.";
115
121
  break;
122
+ case BiometricManager.BIOMETRIC_ERROR_SECURITY_UPDATE_REQUIRED:
123
+ reason = "The user can't authenticate because a security vulnerability has been discovered with one or more hardware sensors.";
124
+ break;
125
+ case BiometricManager.BIOMETRIC_ERROR_UNSUPPORTED:
126
+ reason = "The user can't authenticate because the specified options are incompatible with the current Android version.";
127
+ break;
128
+ case BiometricManager.BIOMETRIC_STATUS_UNKNOWN:
129
+ reason = "Unable to determine whether the user can authenticate.";
130
+ break;
116
131
  }
117
132
 
118
133
  ret.put("reason", reason);
@@ -101,12 +101,6 @@ export interface AuthenticateOptions {
101
101
  * Subtitle for the Android dialog. If not supplied, the system default is used.
102
102
  */
103
103
  androidSubtitle?: string;
104
- /**
105
- * When this many consecutive biometric verification attempts fail,
106
- * `authenticate` returns `BiometryErrorType.authenticationFailed`.
107
- * The default is 3.
108
- */
109
- androidMaxAttempts?: number;
110
104
  }
111
105
  /**
112
106
  * If the `authenticate()` method throws an exception, the error object
@@ -176,8 +170,16 @@ export interface BiometricAuthPlugin extends DecoratedNativePlugin {
176
170
  * Prompt the user for authentication. If authorization fails for any reason,
177
171
  * the promise is rejected with a `BiometryError`.
178
172
  *
179
- * @param {AuthenticateOptions} options
180
- * @returns {Promise<void>}
173
+ * For detailed information about the behavior on iOS, see:
174
+ *
175
+ * https://developer.apple.com/documentation/localauthentication/lapolicy/deviceownerauthenticationwithbiometrics
176
+ *
177
+ * Android imposes a limit of 5 failed attempts. If `allowDeviceCredential` is
178
+ * `true`, the user will then be presented with a device credential prompt.
179
+ * If `allowDeviceCredential` is `false`, `authenticate()` will reject with
180
+ * a `BiometryErrorType` of `biometryLockout`, after which the user will have
181
+ * to wait 30 seconds before being allowed to authenticate again.
182
+ *
181
183
  * @rejects {BiometryError}
182
184
  */
183
185
  authenticate: (options?: AuthenticateOptions) => Promise<void>;
@@ -185,7 +187,6 @@ export interface BiometricAuthPlugin extends DecoratedNativePlugin {
185
187
  * Register a function that will be called when the app resumes.
186
188
  * The function will be passed the result of `checkBiometry()`.
187
189
  *
188
- * @param {ResumeListener} listener
189
190
  * @returns {boolean} true if the listener is successfully added
190
191
  */
191
192
  addResumeListener: (listener: ResumeListener) => Promise<PluginListenerHandle>;
package/dist/esm/index.js CHANGED
@@ -1,8 +1,8 @@
1
1
  import { registerPlugin } from '@capacitor/core';
2
2
  import { kPluginName } from './definitions';
3
- import { name } from './package.json';
3
+ import info from './info.json';
4
4
  import { BiometricAuth } from './web';
5
- console.log(`loaded ${name}`);
5
+ console.log(`loaded ${info.name} v${info.version}`);
6
6
  // Because we are using @aparajita/capacitor-native-decorator,
7
7
  // we have one version of the TS code to rule them all, and there
8
8
  // is no need to lazy load. 😁
@@ -0,0 +1,4 @@
1
+ {
2
+ "name": "@aparajita/capacitor-biometric-auth",
3
+ "version": "3.0.1"
4
+ }
package/dist/esm/web.js CHANGED
@@ -1,9 +1,4 @@
1
- var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
2
- var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
- if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4
- else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
- return c > 3 && r && Object.defineProperty(target, key, r), r;
6
- };
1
+ import { __decorate } from "tslib";
7
2
  import { native } from '@aparajita/capacitor-native-decorator';
8
3
  import { App } from '@capacitor/app';
9
4
  import { WebPlugin } from '@capacitor/core';
@@ -3,6 +3,7 @@
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
5
  var core = require('@capacitor/core');
6
+ var tslib = require('tslib');
6
7
  var capacitorNativeDecorator = require('@aparajita/capacitor-native-decorator');
7
8
  var app = require('@capacitor/app');
8
9
 
@@ -64,14 +65,11 @@ class BiometryError {
64
65
  }
65
66
  const kPluginName = 'BiometricAuth';
66
67
 
67
- const name = "@aparajita/capacitor-biometric-auth";
68
-
69
- var __decorate = (window && window.__decorate) || function (decorators, target, key, desc) {
70
- var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
71
- if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
72
- else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
73
- return c > 3 && r && Object.defineProperty(target, key, r), r;
68
+ var info = {
69
+ name: "@aparajita/capacitor-biometric-auth",
70
+ version: "3.0.1"
74
71
  };
72
+
75
73
  const kBiometryTypeNameMap = {
76
74
  [exports.BiometryType.none]: '',
77
75
  [exports.BiometryType.touchId]: 'Touch ID',
@@ -138,10 +136,10 @@ class BiometricAuth extends core.WebPlugin {
138
136
  });
139
137
  }
140
138
  }
141
- __decorate([
139
+ tslib.__decorate([
142
140
  capacitorNativeDecorator.native()
143
141
  ], BiometricAuth.prototype, "checkBiometry", null);
144
- __decorate([
142
+ tslib.__decorate([
145
143
  capacitorNativeDecorator.native()
146
144
  ], BiometricAuth.prototype, "authenticate", null);
147
145
  /**
@@ -154,7 +152,7 @@ function getBiometryName(type) {
154
152
  return kBiometryTypeNameMap[type] || '';
155
153
  }
156
154
 
157
- console.log(`loaded ${name}`);
155
+ console.log(`loaded ${info.name} v${info.version}`);
158
156
  // Because we are using @aparajita/capacitor-native-decorator,
159
157
  // we have one version of the TS code to rule them all, and there
160
158
  // is no need to lazy load. 😁
package/dist/plugin.js CHANGED
@@ -1,4 +1,4 @@
1
- var capacitorBiometricAuth = (function (exports, core, capacitorNativeDecorator, app) {
1
+ var capacitorBiometricAuth = (function (exports, core, tslib, capacitorNativeDecorator, app) {
2
2
  'use strict';
3
3
 
4
4
  exports.BiometryType = void 0;
@@ -59,14 +59,11 @@ var capacitorBiometricAuth = (function (exports, core, capacitorNativeDecorator,
59
59
  }
60
60
  const kPluginName = 'BiometricAuth';
61
61
 
62
- const name = "@aparajita/capacitor-biometric-auth";
63
-
64
- var __decorate = (window && window.__decorate) || function (decorators, target, key, desc) {
65
- var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
66
- if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
67
- else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
68
- return c > 3 && r && Object.defineProperty(target, key, r), r;
62
+ var info = {
63
+ name: "@aparajita/capacitor-biometric-auth",
64
+ version: "3.0.1"
69
65
  };
66
+
70
67
  const kBiometryTypeNameMap = {
71
68
  [exports.BiometryType.none]: '',
72
69
  [exports.BiometryType.touchId]: 'Touch ID',
@@ -133,10 +130,10 @@ var capacitorBiometricAuth = (function (exports, core, capacitorNativeDecorator,
133
130
  });
134
131
  }
135
132
  }
136
- __decorate([
133
+ tslib.__decorate([
137
134
  capacitorNativeDecorator.native()
138
135
  ], BiometricAuth.prototype, "checkBiometry", null);
139
- __decorate([
136
+ tslib.__decorate([
140
137
  capacitorNativeDecorator.native()
141
138
  ], BiometricAuth.prototype, "authenticate", null);
142
139
  /**
@@ -149,7 +146,7 @@ var capacitorBiometricAuth = (function (exports, core, capacitorNativeDecorator,
149
146
  return kBiometryTypeNameMap[type] || '';
150
147
  }
151
148
 
152
- console.log(`loaded ${name}`);
149
+ console.log(`loaded ${info.name} v${info.version}`);
153
150
  // Because we are using @aparajita/capacitor-native-decorator,
154
151
  // we have one version of the TS code to rule them all, and there
155
152
  // is no need to lazy load. 😁
@@ -169,4 +166,4 @@ var capacitorBiometricAuth = (function (exports, core, capacitorNativeDecorator,
169
166
 
170
167
  return exports;
171
168
 
172
- })({}, capacitorExports, capacitorNativeDecorator, app);
169
+ })({}, capacitorExports, tslib, capacitorNativeDecorator, app);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aparajita/capacitor-biometric-auth",
3
- "version": "2.0.7",
3
+ "version": "3.0.1",
4
4
  "description": "Provides access to the native biometric auth APIs for Capacitor apps",
5
5
  "author": "Aparajita Fishman",
6
6
  "license": "MIT",
@@ -19,6 +19,16 @@
19
19
  "*.podspec",
20
20
  "LICENSE"
21
21
  ],
22
+ "commit-and-tag-version": {
23
+ "scripts": {
24
+ "postbump": "pnpm -s builder"
25
+ }
26
+ },
27
+ "ultra": {
28
+ "concurrent": [
29
+ "verify"
30
+ ]
31
+ },
22
32
  "keywords": [
23
33
  "capacitor",
24
34
  "plugin",
@@ -48,70 +58,62 @@
48
58
  "devDependencies": {
49
59
  "@aparajita/capacitor-docgen": "github:aparajita/capacitor-docgen",
50
60
  "@aparajita/capacitor-docgen-format": "github:aparajita/capacitor-docgen-format",
51
- "@aparajita/eslint-config-base": "^1.1.4",
61
+ "@aparajita/eslint-config-base": "^1.1.5",
52
62
  "@aparajita/prettier-config": "^1.0.0",
53
63
  "@aparajita/swiftly": "^1.0.4",
54
- "@capacitor/core": "^3.6.0",
64
+ "@capacitor/cli": "^4.0.1",
65
+ "@commitlint/cli": "^17.0.3",
66
+ "@commitlint/config-conventional": "^17.0.3",
55
67
  "@ionic/swiftlint-config": "^1.1.2",
56
68
  "@rollup/plugin-json": "^4.1.0",
57
- "@types/node": "^18.0.6",
58
- "@typescript-eslint/eslint-plugin": "^5.30.7",
59
- "@typescript-eslint/parser": "^5.30.7",
60
- "chalk": "^5.0.1",
69
+ "@types/node": "^18.6.3",
70
+ "@typescript-eslint/eslint-plugin": "^5.32.0",
71
+ "@typescript-eslint/parser": "^5.32.0",
61
72
  "commit-and-tag-version": "^10.0.1",
62
- "eslint": "^8.20.0",
73
+ "eslint": "^8.21.0",
63
74
  "eslint-config-prettier": "^8.5.0",
64
75
  "eslint-config-standard": "^17.0.0",
65
- "eslint-import-resolver-typescript": "^3.2.7",
76
+ "eslint-import-resolver-typescript": "^3.4.0",
66
77
  "eslint-plugin-import": "^2.26.0",
67
78
  "eslint-plugin-n": "^15.2.4",
68
79
  "eslint-plugin-prettier": "^4.2.1",
69
80
  "eslint-plugin-promise": "^6.0.0",
81
+ "husky": "^8.0.1",
70
82
  "nodemon": "^2.0.19",
71
83
  "prettier": "^2.7.1",
72
84
  "prettier-plugin-java": "^1.6.2",
73
85
  "rimraf": "^3.0.2",
74
- "rollup": "^2.77.0",
86
+ "rollup": "^2.77.2",
75
87
  "swiftlint": "^1.0.1",
76
- "typescript": "~4.7.4"
88
+ "typescript": "~4.7.4",
89
+ "ultra-runner": "^3.10.5"
77
90
  },
78
91
  "dependencies": {
79
- "@aparajita/capacitor-native-decorator": "^2.0.7",
80
- "@capacitor/android": "^3.6.0",
81
- "@capacitor/app": "^1.1.1",
82
- "@capacitor/ios": "^3.6.0"
83
- },
84
- "peerDependencies": {
85
- "@capacitor/core": "^3.6.0"
92
+ "@aparajita/capacitor-native-decorator": "^3.0.0",
93
+ "@capacitor/android": "^4.0.1",
94
+ "@capacitor/app": "^4.0.1",
95
+ "@capacitor/core": "^4.0.1",
96
+ "@capacitor/ios": "^4.0.1",
97
+ "tslib": "^2.4.0"
86
98
  },
87
99
  "scripts": {
88
- "clean": "rimraf ./dist",
89
- "build": "pnpm check.fix && pnpm builder",
90
- "build.dev": "pnpm check.fix && pnpm builder.dev",
91
- "builder": "pnpm clean && tsc $SOURCE_MAP && pnpm rollup && make-ios-plugin && pnpm docgen",
92
- "builder.dev": "SOURCE_MAP=--sourceMap pnpm builder",
93
- "rollup": "rollup -c rollup.config.mjs",
94
- "watcher": "nodemon -w ./src -w tsconfig.json -w rollup.config.mjs --exec 'pnpm $BUILD --silent' -e ts",
95
- "watch": "BUILD=build pnpm watcher",
96
- "watch.dev": "BUILD=build.dev pnpm watcher",
97
- "lint": "eslint --cache . && pnpm typecheck",
98
- "lint.fix": "eslint --cache --fix . && pnpm typecheck",
99
- "typecheck": "tsc --noEmit",
100
- "lint.swift": "pnpm swiftlint",
101
- "prettier": "prettier --check \"**/*.{css,html,ts,js,json,java}\"",
102
- "prettier.fix": "pnpm prettier --write",
103
- "swiftlint": "swiftly ios",
104
- "swiftlint.fix": "swiftly --fix ios",
105
- "check": "pnpm lint && pnpm prettier && pnpm swiftlint",
106
- "check.fix": "pnpm lint.fix && pnpm prettier.fix && pnpm swiftlint.fix",
107
- "docgen": "docgen --api BiometricAuthPlugin --output-readme README.md && docgen-format",
108
- "verify": "pnpm verify:ios && pnpm verify:android && pnpm verify:web",
109
- "verify:ios": "cd ios && pod install && xcodebuild -workspace Plugin.xcworkspace -scheme Plugin && cd ..",
110
- "verify:android": "cd android && ./gradlew clean build test && cd ..",
111
- "verify:web": "pnpm build",
112
- "push": "git push --follow-tags origin main",
113
- "release.check": "pnpm check.fix && commit-and-tag-version ${VERSION:+-r $VERSION} --dry-run",
114
- "release.prepare": "commit-and-tag-version ${VERSION:+-r $VERSION} && pnpm builder",
115
- "release": "pnpm push && pnpm publish"
100
+ "extract-info": "node scripts/extractPackageInfo.js",
101
+ "lint.eslint": "eslint --fix --cache --ext .js,.cjs,.mjs,.ts --max-warnings 0",
102
+ "lint.prettier": "prettier --write --cache --list-different",
103
+ "lint.tsc": "tsc --noEmit",
104
+ "lint": "pnpm -s extract-info && pnpm -s lint.eslint . && pnpm -s lint.prettier . && pnpm -s lint.tsc",
105
+ "tsc": "tsc ${SOURCE_MAP}",
106
+ "builder": "pnpm -s extract-info && rimraf dist && pnpm -s tsc && rollup -c rollup.config.mjs && pnpm -s docgen",
107
+ "build": "pnpm -s builder",
108
+ "build.dev": "SOURCE_MAP=--sourceMap pnpm -s builder",
109
+ "watch": "nodemon --exec 'pnpm -s build.dev'",
110
+ "docgen": "docgen --api BiometricAuthPlugin --output-readme README.md && docgen-format && pnpm -s lint.prettier README.md",
111
+ "open.ios": "open ios/Plugin.xcworkspace",
112
+ "open.android": "open -b com.google.android.studio android",
113
+ "verify.ios": "cd ios && pod install && xcodebuild -workspace Plugin.xcworkspace -scheme Plugin -quiet && cd ..",
114
+ "verify.android": "cd android && ./gradlew clean build test && cd ..",
115
+ "verify": "pnpm verify.ios && pnpm verify.android",
116
+ "release.pre": "scripts/ensure-clean.sh && pnpm -s lint",
117
+ "release": "pnpm -s release.pre && commit-and-tag-version && git push --follow-tags && pnpm publish"
116
118
  }
117
119
  }
@@ -1,117 +0,0 @@
1
- {
2
- "name": "@aparajita/capacitor-biometric-auth",
3
- "version": "2.0.7",
4
- "description": "Provides access to the native biometric auth APIs for Capacitor apps",
5
- "author": "Aparajita Fishman",
6
- "license": "MIT",
7
- "main": "dist/plugin.cjs.js",
8
- "module": "dist/esm/index.js",
9
- "types": "dist/esm/index.d.ts",
10
- "unpkg": "dist/plugin.js",
11
- "engines": {
12
- "node": ">=16.15.1"
13
- },
14
- "files": [
15
- "android/src/main/",
16
- "android/build.gradle",
17
- "dist/",
18
- "ios/Plugin/",
19
- "*.podspec",
20
- "LICENSE"
21
- ],
22
- "scripts": {
23
- "clean": "rimraf ./dist",
24
- "build": "pnpm check.fix && pnpm builder",
25
- "build.dev": "pnpm check.fix && pnpm builder.dev",
26
- "builder": "pnpm clean && tsc $SOURCE_MAP && pnpm rollup && make-ios-plugin && pnpm docgen",
27
- "builder.dev": "SOURCE_MAP=--sourceMap pnpm builder",
28
- "rollup": "rollup -c rollup.config.mjs",
29
- "watcher": "nodemon -w ./src -w tsconfig.json -w rollup.config.mjs --exec 'pnpm $BUILD --silent' -e ts",
30
- "watch": "BUILD=build pnpm watcher",
31
- "watch.dev": "BUILD=build.dev pnpm watcher",
32
- "lint": "eslint --cache . && pnpm typecheck",
33
- "lint.fix": "eslint --cache --fix . && pnpm typecheck",
34
- "typecheck": "tsc --noEmit",
35
- "lint.swift": "pnpm swiftlint",
36
- "prettier": "prettier --check \"**/*.{css,html,ts,js,json,java}\"",
37
- "prettier.fix": "pnpm prettier --write",
38
- "swiftlint": "swiftly ios",
39
- "swiftlint.fix": "swiftly --fix ios",
40
- "check": "pnpm lint && pnpm prettier && pnpm swiftlint",
41
- "check.fix": "pnpm lint.fix && pnpm prettier.fix && pnpm swiftlint.fix",
42
- "docgen": "docgen --api BiometricAuthPlugin --output-readme README.md && docgen-format",
43
- "verify": "pnpm verify:ios && pnpm verify:android && pnpm verify:web",
44
- "verify:ios": "cd ios && pod install && xcodebuild -workspace Plugin.xcworkspace -scheme Plugin && cd ..",
45
- "verify:android": "cd android && ./gradlew clean build test && cd ..",
46
- "verify:web": "pnpm build",
47
- "push": "git push --follow-tags origin main",
48
- "release.check": "pnpm check.fix && commit-and-tag-version ${VERSION:+-r $VERSION} --dry-run",
49
- "release.prepare": "commit-and-tag-version ${VERSION:+-r $VERSION} && pnpm builder",
50
- "release": "pnpm push && pnpm publish"
51
- },
52
- "keywords": [
53
- "capacitor",
54
- "plugin",
55
- "native",
56
- "biometry",
57
- "biometric",
58
- "auth",
59
- "faceid",
60
- "touchid"
61
- ],
62
- "capacitor": {
63
- "ios": {
64
- "src": "ios"
65
- },
66
- "android": {
67
- "src": "android"
68
- }
69
- },
70
- "swiftlint": "@ionic/swiftlint-config",
71
- "repository": {
72
- "type": "git",
73
- "url": "https://github.com/aparajita/capacitor-biometric-auth.git"
74
- },
75
- "bugs": {
76
- "url": "https://github.com/aparajita/capacitor-biometric-auth/issues"
77
- },
78
- "devDependencies": {
79
- "@aparajita/capacitor-docgen": "github:aparajita/capacitor-docgen",
80
- "@aparajita/capacitor-docgen-format": "github:aparajita/capacitor-docgen-format",
81
- "@aparajita/eslint-config-base": "^1.1.4",
82
- "@aparajita/prettier-config": "^1.0.0",
83
- "@aparajita/swiftly": "^1.0.4",
84
- "@capacitor/core": "^3.6.0",
85
- "@ionic/swiftlint-config": "^1.1.2",
86
- "@rollup/plugin-json": "^4.1.0",
87
- "@types/node": "^18.0.6",
88
- "@typescript-eslint/eslint-plugin": "^5.30.7",
89
- "@typescript-eslint/parser": "^5.30.7",
90
- "chalk": "^5.0.1",
91
- "commit-and-tag-version": "^10.0.1",
92
- "eslint": "^8.20.0",
93
- "eslint-config-prettier": "^8.5.0",
94
- "eslint-config-standard": "^17.0.0",
95
- "eslint-import-resolver-typescript": "^3.2.7",
96
- "eslint-plugin-import": "^2.26.0",
97
- "eslint-plugin-n": "^15.2.4",
98
- "eslint-plugin-prettier": "^4.2.1",
99
- "eslint-plugin-promise": "^6.0.0",
100
- "nodemon": "^2.0.19",
101
- "prettier": "^2.7.1",
102
- "prettier-plugin-java": "^1.6.2",
103
- "rimraf": "^3.0.2",
104
- "rollup": "^2.77.0",
105
- "swiftlint": "^1.0.1",
106
- "typescript": "~4.7.4"
107
- },
108
- "dependencies": {
109
- "@aparajita/capacitor-native-decorator": "^2.0.7",
110
- "@capacitor/android": "^3.6.0",
111
- "@capacitor/app": "^1.1.1",
112
- "@capacitor/ios": "^3.6.0"
113
- },
114
- "peerDependencies": {
115
- "@capacitor/core": "^3.6.0"
116
- }
117
- }