@aparajita/capacitor-biometric-auth 3.1.4 → 5.0.0

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/README.md CHANGED
@@ -32,7 +32,7 @@ The API is extensively documented in the [TypeScript definitions file](src/defin
32
32
 
33
33
  ### Checking availability
34
34
 
35
- 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.
35
+ 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` and `code` will tell you why.
36
36
 
37
37
  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.
38
38
 
@@ -109,7 +109,7 @@ web only<br><br>On the web, this method allows you to dynamically simulate diffe
109
109
  authenticate(options?: AuthenticateOptions) => Promise<void>
110
110
  ```
111
111
 
112
- 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>Some versions of Android impose a limit on the number of failed attempts. If `allowDeviceCredential` is `true`, when the limit is reached the user will then be presented with a device credential prompt. If `allowDeviceCredential` is `false`, when the limit is reached `authenticate()` will reject with a `BiometryErrorType` of `biometryLockout`, after which the user will have to wait the system-defined length of time before being allowed to authenticate again.
112
+ 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>Some versions of Android impose a limit on the number of failed attempts. If `allowDeviceCredential` is `true`, when the limit is reached the user will then be presented with a device credential prompt. If `allowDeviceCredential` is `false`, when the limit is reached `authenticate()` will reject with a <a href="#biometryerrortype">`BiometryErrorType`</a> of `biometryLockout`, after which the user will have to wait the system-defined length of time before being allowed to authenticate again.
113
113
 
114
114
  | Param | Type |
115
115
  | :------ | :----------------------------------------------------- |
@@ -137,11 +137,12 @@ Register a function that will be called when the app resumes. The function will
137
137
 
138
138
  #### CheckBiometryResult
139
139
 
140
- | Prop | Type | Description |
141
- | :----------- | :--------------------------------------- | :------------------------------------------------------------------------------------------------------------------------ |
142
- | isAvailable | boolean | True if the device has biometric authentication capability and the current user has enrolled in biometry. |
143
- | biometryType | <a href="#biometrytype">BiometryType</a> | The type of biometry available on the device. |
144
- | 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. |
140
+ | Prop | Type | Description |
141
+ | :----------- | :------------------------------------------------- | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
142
+ | isAvailable | boolean | True if the device has biometric authentication capability and the current user has enrolled in biometry. |
143
+ | biometryType | <a href="#biometrytype">BiometryType</a> | The type of biometry available on the device. |
144
+ | 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. |
145
+ | code | <a href="#biometryerrortype">BiometryErrorType</a> | If biometry is not available, the error code will be returned here. Otherwise it's an empty string. The error code will be one of the <a href="#biometryerrortype">`BiometryErrorType`</a> enum values, and is consistent across platforms. This allows you to check for specific errors in a platform- independent way, for example:<br><br>if (result.code === <a href="#biometryerrortype">BiometryErrorType.biometryNotEnrolled</a>) { ... } |
145
146
 
146
147
  #### AuthenticateOptions
147
148
 
@@ -181,5 +182,23 @@ The signature of the callback passed to `addResumeListener()`.
181
182
  | faceAuthentication | Android face authentication is available |
182
183
  | irisAuthentication | Android iris authentication is available |
183
184
 
185
+ #### BiometryErrorType
186
+
187
+ | Members | Value |
188
+ | :------------------- | :--------------------- |
189
+ | none | '' |
190
+ | appCancel | 'appCancel' |
191
+ | authenticationFailed | 'authenticationFailed' |
192
+ | invalidContext | 'invalidContext' |
193
+ | notInteractive | 'notInteractive' |
194
+ | passcodeNotSet | 'passcodeNotSet' |
195
+ | systemCancel | 'systemCancel' |
196
+ | userCancel | 'userCancel' |
197
+ | userFallback | 'userFallback' |
198
+ | biometryLockout | 'biometryLockout' |
199
+ | biometryNotAvailable | 'biometryNotAvailable' |
200
+ | biometryNotEnrolled | 'biometryNotEnrolled' |
201
+ | noDeviceCredential | 'noDeviceCredential' |
202
+
184
203
  </docgen-api>
185
204
  </div>
@@ -1,7 +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.3'
4
- androidxEspressoCoreVersion = project.hasProperty('androidxEspressoCoreVersion') ? rootProject.ext.androidxEspressoCoreVersion : '3.4.0'
3
+ androidxAppCompatVersion = project.hasProperty('androidxAppCompatVersion') ? rootProject.ext.androidxAppCompatVersion : '1.6.1'
4
+ androidxJunitVersion = project.hasProperty('androidxJunitVersion') ? rootProject.ext.androidxJunitVersion : '1.1.5'
5
+ androidxEspressoCoreVersion = project.hasProperty('androidxEspressoCoreVersion') ? rootProject.ext.androidxEspressoCoreVersion : '3.5.1'
5
6
  }
6
7
 
7
8
  buildscript {
@@ -10,17 +11,18 @@ buildscript {
10
11
  mavenCentral()
11
12
  }
12
13
  dependencies {
13
- classpath 'com.android.tools.build:gradle:4.1.3'
14
+ classpath 'com.android.tools.build:gradle:8.0.2'
14
15
  }
15
16
  }
16
17
 
17
18
  apply plugin: 'com.android.library'
18
19
 
19
20
  android {
20
- compileSdkVersion project.hasProperty('compileSdkVersion') ? rootProject.ext.compileSdkVersion : 32
21
+ namespace "com.aparajita.capacitor.biometricauth"
22
+ compileSdkVersion project.hasProperty('compileSdkVersion') ? rootProject.ext.compileSdkVersion : 33
21
23
  defaultConfig {
22
24
  minSdkVersion project.hasProperty('minSdkVersion') ? rootProject.ext.minSdkVersion : 22
23
- targetSdkVersion project.hasProperty('targetSdkVersion') ? rootProject.ext.targetSdkVersion : 32
25
+ targetSdkVersion project.hasProperty('targetSdkVersion') ? rootProject.ext.targetSdkVersion : 33
24
26
  versionCode 1
25
27
  versionName "1.0"
26
28
  testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
@@ -35,8 +37,8 @@ android {
35
37
  abortOnError false
36
38
  }
37
39
  compileOptions {
38
- sourceCompatibility JavaVersion.VERSION_11
39
- targetCompatibility JavaVersion.VERSION_11
40
+ sourceCompatibility JavaVersion.VERSION_17
41
+ targetCompatibility JavaVersion.VERSION_17
40
42
  }
41
43
  }
42
44
 
@@ -50,11 +52,11 @@ dependencies {
50
52
  implementation 'androidx.biometric:biometric:1.1.0'
51
53
  implementation fileTree(dir: 'libs', include: ['*.jar'])
52
54
  implementation project(':capacitor-android')
53
- implementation 'androidx.appcompat:appcompat:1.4.2'
54
- implementation 'com.google.android.material:material:1.6.1'
55
+ implementation 'androidx.appcompat:appcompat:1.6.1'
56
+ implementation 'com.google.android.material:material:1.9.0'
55
57
  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'
58
+ implementation 'androidx.navigation:navigation-fragment:2.6.0'
59
+ implementation 'androidx.navigation:navigation-ui:2.6.0'
58
60
  testImplementation "junit:junit:$junitVersion"
59
61
  androidTestImplementation "androidx.test.ext:junit:$androidxJunitVersion"
60
62
  androidTestImplementation "androidx.test.espresso:espresso-core:$androidxEspressoCoreVersion"
@@ -1,6 +1,6 @@
1
1
  <?xml version="1.0" encoding="utf-8"?>
2
2
  <manifest xmlns:android="http://schemas.android.com/apk/res/android"
3
- package="com.aparajita.capacitor.biometricauth">
3
+ >
4
4
 
5
5
  <application>
6
6
  <activity
@@ -35,10 +35,6 @@ public class AuthActivity extends AppCompatActivity {
35
35
  String title = intent.getStringExtra(BiometricAuthNative.TITLE);
36
36
  String subtitle = intent.getStringExtra(BiometricAuthNative.SUBTITLE);
37
37
  String description = intent.getStringExtra(BiometricAuthNative.REASON);
38
- final int maxAttempts = intent.getIntExtra(
39
- BiometricAuthNative.MAX_ATTEMPTS,
40
- BiometricAuthNative.DEFAULT_MAX_ATTEMPTS
41
- );
42
38
  allowDeviceCredential = false;
43
39
 
44
40
  if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
@@ -120,17 +120,24 @@ public class BiometricAuthNative extends Plugin {
120
120
  reason = "There is no biometric hardware on this device.";
121
121
  break;
122
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.";
123
+ reason = "The user cant authenticate because a security vulnerability has been discovered with one or more hardware sensors.";
124
124
  break;
125
125
  case BiometricManager.BIOMETRIC_ERROR_UNSUPPORTED:
126
- reason = "The user can't authenticate because the specified options are incompatible with the current Android version.";
126
+ reason = "The user cant authenticate because the specified options are incompatible with the current Android version.";
127
127
  break;
128
128
  case BiometricManager.BIOMETRIC_STATUS_UNKNOWN:
129
129
  reason = "Unable to determine whether the user can authenticate.";
130
130
  break;
131
131
  }
132
132
 
133
+ String errorCode = biometryErrorCodeMap.get(biometryResult);
134
+
135
+ if (errorCode == null) {
136
+ errorCode = "biometryNotAvailable";
137
+ }
138
+
133
139
  ret.put("reason", reason);
140
+ ret.put("code", errorCode);
134
141
  call.resolve(ret);
135
142
  }
136
143
 
@@ -110,18 +110,19 @@ export interface AuthenticateOptions {
110
110
  * for a description of each error code.
111
111
  */
112
112
  export declare enum BiometryErrorType {
113
- appCancel = 0,
114
- authenticationFailed = 1,
115
- invalidContext = 2,
116
- notInteractive = 3,
117
- passcodeNotSet = 4,
118
- systemCancel = 5,
119
- userCancel = 6,
120
- userFallback = 7,
121
- biometryLockout = 8,
122
- biometryNotAvailable = 9,
123
- biometryNotEnrolled = 10,
124
- noDeviceCredential = 11
113
+ none = "",
114
+ appCancel = "appCancel",
115
+ authenticationFailed = "authenticationFailed",
116
+ invalidContext = "invalidContext",
117
+ notInteractive = "notInteractive",
118
+ passcodeNotSet = "passcodeNotSet",
119
+ systemCancel = "systemCancel",
120
+ userCancel = "userCancel",
121
+ userFallback = "userFallback",
122
+ biometryLockout = "biometryLockout",
123
+ biometryNotAvailable = "biometryNotAvailable",
124
+ biometryNotEnrolled = "biometryNotEnrolled",
125
+ noDeviceCredential = "noDeviceCredential"
125
126
  }
126
127
  export interface ResultError extends PluginResultError {
127
128
  code: string;
@@ -146,11 +147,23 @@ export interface CheckBiometryResult {
146
147
  * it will be returned here. Otherwise it's an empty string.
147
148
  */
148
149
  reason: string;
150
+ /**
151
+ * If biometry is not available, the error code will be returned here.
152
+ * Otherwise it's an empty string. The error code will be one of the
153
+ * `BiometryErrorType` enum values, and is consistent across
154
+ * platforms. This allows you to check for specific errors in a platform-
155
+ * independent way, for example:
156
+ *
157
+ * if (result.code === BiometryErrorType.biometryNotEnrolled) {
158
+ * ...
159
+ * }
160
+ */
161
+ code: BiometryErrorType;
149
162
  }
150
163
  /**
151
164
  * The signature of the callback passed to `addResumeListener()`.
152
165
  */
153
- export declare type ResumeListener = (info: CheckBiometryResult) => void;
166
+ export type ResumeListener = (info: CheckBiometryResult) => void;
154
167
  export interface BiometricAuthPlugin extends WebPlugin {
155
168
  /**
156
169
  * Check to see what biometry type (if any) is available.
@@ -35,22 +35,23 @@ export var BiometryType;
35
35
  */
36
36
  export var BiometryErrorType;
37
37
  (function (BiometryErrorType) {
38
- BiometryErrorType[BiometryErrorType["appCancel"] = 0] = "appCancel";
39
- BiometryErrorType[BiometryErrorType["authenticationFailed"] = 1] = "authenticationFailed";
40
- BiometryErrorType[BiometryErrorType["invalidContext"] = 2] = "invalidContext";
41
- BiometryErrorType[BiometryErrorType["notInteractive"] = 3] = "notInteractive";
42
- BiometryErrorType[BiometryErrorType["passcodeNotSet"] = 4] = "passcodeNotSet";
43
- BiometryErrorType[BiometryErrorType["systemCancel"] = 5] = "systemCancel";
44
- BiometryErrorType[BiometryErrorType["userCancel"] = 6] = "userCancel";
45
- BiometryErrorType[BiometryErrorType["userFallback"] = 7] = "userFallback";
46
- BiometryErrorType[BiometryErrorType["biometryLockout"] = 8] = "biometryLockout";
47
- BiometryErrorType[BiometryErrorType["biometryNotAvailable"] = 9] = "biometryNotAvailable";
48
- BiometryErrorType[BiometryErrorType["biometryNotEnrolled"] = 10] = "biometryNotEnrolled";
49
- BiometryErrorType[BiometryErrorType["noDeviceCredential"] = 11] = "noDeviceCredential";
38
+ BiometryErrorType["none"] = "";
39
+ BiometryErrorType["appCancel"] = "appCancel";
40
+ BiometryErrorType["authenticationFailed"] = "authenticationFailed";
41
+ BiometryErrorType["invalidContext"] = "invalidContext";
42
+ BiometryErrorType["notInteractive"] = "notInteractive";
43
+ BiometryErrorType["passcodeNotSet"] = "passcodeNotSet";
44
+ BiometryErrorType["systemCancel"] = "systemCancel";
45
+ BiometryErrorType["userCancel"] = "userCancel";
46
+ BiometryErrorType["userFallback"] = "userFallback";
47
+ BiometryErrorType["biometryLockout"] = "biometryLockout";
48
+ BiometryErrorType["biometryNotAvailable"] = "biometryNotAvailable";
49
+ BiometryErrorType["biometryNotEnrolled"] = "biometryNotEnrolled";
50
+ BiometryErrorType["noDeviceCredential"] = "noDeviceCredential";
50
51
  })(BiometryErrorType || (BiometryErrorType = {}));
51
52
  export class BiometryError {
52
53
  constructor(message, code) {
53
54
  this.message = message;
54
- this.code = BiometryErrorType[code];
55
+ this.code = code;
55
56
  }
56
57
  }
package/dist/esm/index.js CHANGED
@@ -1,10 +1,8 @@
1
1
  import { registerPlugin } from '@capacitor/core';
2
- import info from './info.json';
3
- console.log(`loaded ${info.name} v${info.version}`);
4
2
  const proxy = registerPlugin('BiometricAuthNative', {
5
3
  web: async () => import('./web').then((module) => new module.BiometricAuthWeb()),
6
4
  ios: async () => import('./native').then((module) => new module.BiometricAuthNative(proxy)),
7
- android: async () => import('./native').then((module) => new module.BiometricAuthNative(proxy))
5
+ android: async () => import('./native').then((module) => new module.BiometricAuthNative(proxy)),
8
6
  });
9
7
  export * from './definitions';
10
8
  export * from './web-utils';
@@ -1,5 +1,5 @@
1
1
  import { BiometricAuthBase } from './base';
2
- import { BiometryType } from './definitions';
2
+ import { BiometryErrorType, BiometryType } from './definitions';
3
3
  // eslint-disable-next-line import/prefer-default-export
4
4
  export class BiometricAuthNative extends BiometricAuthBase {
5
5
  constructor(capProxy) {
@@ -12,7 +12,8 @@ export class BiometricAuthNative extends BiometricAuthBase {
12
12
  return Promise.resolve({
13
13
  isAvailable: true,
14
14
  biometryType: BiometryType.none,
15
- reason: ''
15
+ reason: '',
16
+ code: BiometryErrorType.none,
16
17
  });
17
18
  }
18
19
  // eslint-disable-next-line @typescript-eslint/no-unused-vars,@typescript-eslint/no-empty-function
@@ -5,7 +5,7 @@ const kBiometryTypeNameMap = {
5
5
  [BiometryType.faceId]: 'Face ID',
6
6
  [BiometryType.fingerprintAuthentication]: 'Fingerprint Authentication',
7
7
  [BiometryType.faceAuthentication]: 'Face Authentication',
8
- [BiometryType.irisAuthentication]: 'Iris Authentication'
8
+ [BiometryType.irisAuthentication]: 'Iris Authentication',
9
9
  };
10
10
  /**
11
11
  * Return a human-readable name for a BiometryType.
package/dist/esm/web.js CHANGED
@@ -11,7 +11,8 @@ export class BiometricAuthWeb extends BiometricAuthBase {
11
11
  return Promise.resolve({
12
12
  isAvailable: this.biometryType !== BiometryType.none,
13
13
  biometryType: this.biometryType,
14
- reason: ''
14
+ reason: '',
15
+ code: BiometryErrorType.none,
15
16
  });
16
17
  }
17
18
  async authenticate(options) {
@@ -1,15 +1,8 @@
1
1
  'use strict';
2
2
 
3
- Object.defineProperty(exports, '__esModule', { value: true });
4
-
5
3
  var core = require('@capacitor/core');
6
4
  var app = require('@capacitor/app');
7
5
 
8
- var info = {
9
- name: "@aparajita/capacitor-biometric-auth",
10
- version: "3.1.4"
11
- };
12
-
13
6
  exports.BiometryType = void 0;
14
7
  (function (BiometryType) {
15
8
  /**
@@ -47,23 +40,24 @@ exports.BiometryType = void 0;
47
40
  */
48
41
  exports.BiometryErrorType = void 0;
49
42
  (function (BiometryErrorType) {
50
- BiometryErrorType[BiometryErrorType["appCancel"] = 0] = "appCancel";
51
- BiometryErrorType[BiometryErrorType["authenticationFailed"] = 1] = "authenticationFailed";
52
- BiometryErrorType[BiometryErrorType["invalidContext"] = 2] = "invalidContext";
53
- BiometryErrorType[BiometryErrorType["notInteractive"] = 3] = "notInteractive";
54
- BiometryErrorType[BiometryErrorType["passcodeNotSet"] = 4] = "passcodeNotSet";
55
- BiometryErrorType[BiometryErrorType["systemCancel"] = 5] = "systemCancel";
56
- BiometryErrorType[BiometryErrorType["userCancel"] = 6] = "userCancel";
57
- BiometryErrorType[BiometryErrorType["userFallback"] = 7] = "userFallback";
58
- BiometryErrorType[BiometryErrorType["biometryLockout"] = 8] = "biometryLockout";
59
- BiometryErrorType[BiometryErrorType["biometryNotAvailable"] = 9] = "biometryNotAvailable";
60
- BiometryErrorType[BiometryErrorType["biometryNotEnrolled"] = 10] = "biometryNotEnrolled";
61
- BiometryErrorType[BiometryErrorType["noDeviceCredential"] = 11] = "noDeviceCredential";
43
+ BiometryErrorType["none"] = "";
44
+ BiometryErrorType["appCancel"] = "appCancel";
45
+ BiometryErrorType["authenticationFailed"] = "authenticationFailed";
46
+ BiometryErrorType["invalidContext"] = "invalidContext";
47
+ BiometryErrorType["notInteractive"] = "notInteractive";
48
+ BiometryErrorType["passcodeNotSet"] = "passcodeNotSet";
49
+ BiometryErrorType["systemCancel"] = "systemCancel";
50
+ BiometryErrorType["userCancel"] = "userCancel";
51
+ BiometryErrorType["userFallback"] = "userFallback";
52
+ BiometryErrorType["biometryLockout"] = "biometryLockout";
53
+ BiometryErrorType["biometryNotAvailable"] = "biometryNotAvailable";
54
+ BiometryErrorType["biometryNotEnrolled"] = "biometryNotEnrolled";
55
+ BiometryErrorType["noDeviceCredential"] = "noDeviceCredential";
62
56
  })(exports.BiometryErrorType || (exports.BiometryErrorType = {}));
63
57
  class BiometryError {
64
58
  constructor(message, code) {
65
59
  this.message = message;
66
- this.code = exports.BiometryErrorType[code];
60
+ this.code = code;
67
61
  }
68
62
  }
69
63
 
@@ -73,7 +67,7 @@ const kBiometryTypeNameMap = {
73
67
  [exports.BiometryType.faceId]: 'Face ID',
74
68
  [exports.BiometryType.fingerprintAuthentication]: 'Fingerprint Authentication',
75
69
  [exports.BiometryType.faceAuthentication]: 'Face Authentication',
76
- [exports.BiometryType.irisAuthentication]: 'Iris Authentication'
70
+ [exports.BiometryType.irisAuthentication]: 'Iris Authentication',
77
71
  };
78
72
  /**
79
73
  * Return a human-readable name for a BiometryType.
@@ -83,11 +77,10 @@ function getBiometryName(type) {
83
77
  return kBiometryTypeNameMap[type] || '';
84
78
  }
85
79
 
86
- console.log(`loaded ${info.name} v${info.version}`);
87
80
  const proxy = core.registerPlugin('BiometricAuthNative', {
88
81
  web: async () => Promise.resolve().then(function () { return web; }).then((module) => new module.BiometricAuthWeb()),
89
82
  ios: async () => Promise.resolve().then(function () { return native; }).then((module) => new module.BiometricAuthNative(proxy)),
90
- android: async () => Promise.resolve().then(function () { return native; }).then((module) => new module.BiometricAuthNative(proxy))
83
+ android: async () => Promise.resolve().then(function () { return native; }).then((module) => new module.BiometricAuthNative(proxy)),
91
84
  });
92
85
 
93
86
  // eslint-disable-next-line import/prefer-default-export
@@ -115,7 +108,8 @@ class BiometricAuthWeb extends BiometricAuthBase {
115
108
  return Promise.resolve({
116
109
  isAvailable: this.biometryType !== exports.BiometryType.none,
117
110
  biometryType: this.biometryType,
118
- reason: ''
111
+ reason: '',
112
+ code: exports.BiometryErrorType.none,
119
113
  });
120
114
  }
121
115
  async authenticate(options) {
@@ -167,7 +161,8 @@ class BiometricAuthNative extends BiometricAuthBase {
167
161
  return Promise.resolve({
168
162
  isAvailable: true,
169
163
  biometryType: exports.BiometryType.none,
170
- reason: ''
164
+ reason: '',
165
+ code: exports.BiometryErrorType.none,
171
166
  });
172
167
  }
173
168
  // eslint-disable-next-line @typescript-eslint/no-unused-vars,@typescript-eslint/no-empty-function
package/dist/plugin.js CHANGED
@@ -1,11 +1,6 @@
1
1
  var capacitorBiometricAuth = (function (exports, core, app) {
2
2
  'use strict';
3
3
 
4
- var info = {
5
- name: "@aparajita/capacitor-biometric-auth",
6
- version: "3.1.4"
7
- };
8
-
9
4
  exports.BiometryType = void 0;
10
5
  (function (BiometryType) {
11
6
  /**
@@ -43,23 +38,24 @@ var capacitorBiometricAuth = (function (exports, core, app) {
43
38
  */
44
39
  exports.BiometryErrorType = void 0;
45
40
  (function (BiometryErrorType) {
46
- BiometryErrorType[BiometryErrorType["appCancel"] = 0] = "appCancel";
47
- BiometryErrorType[BiometryErrorType["authenticationFailed"] = 1] = "authenticationFailed";
48
- BiometryErrorType[BiometryErrorType["invalidContext"] = 2] = "invalidContext";
49
- BiometryErrorType[BiometryErrorType["notInteractive"] = 3] = "notInteractive";
50
- BiometryErrorType[BiometryErrorType["passcodeNotSet"] = 4] = "passcodeNotSet";
51
- BiometryErrorType[BiometryErrorType["systemCancel"] = 5] = "systemCancel";
52
- BiometryErrorType[BiometryErrorType["userCancel"] = 6] = "userCancel";
53
- BiometryErrorType[BiometryErrorType["userFallback"] = 7] = "userFallback";
54
- BiometryErrorType[BiometryErrorType["biometryLockout"] = 8] = "biometryLockout";
55
- BiometryErrorType[BiometryErrorType["biometryNotAvailable"] = 9] = "biometryNotAvailable";
56
- BiometryErrorType[BiometryErrorType["biometryNotEnrolled"] = 10] = "biometryNotEnrolled";
57
- BiometryErrorType[BiometryErrorType["noDeviceCredential"] = 11] = "noDeviceCredential";
41
+ BiometryErrorType["none"] = "";
42
+ BiometryErrorType["appCancel"] = "appCancel";
43
+ BiometryErrorType["authenticationFailed"] = "authenticationFailed";
44
+ BiometryErrorType["invalidContext"] = "invalidContext";
45
+ BiometryErrorType["notInteractive"] = "notInteractive";
46
+ BiometryErrorType["passcodeNotSet"] = "passcodeNotSet";
47
+ BiometryErrorType["systemCancel"] = "systemCancel";
48
+ BiometryErrorType["userCancel"] = "userCancel";
49
+ BiometryErrorType["userFallback"] = "userFallback";
50
+ BiometryErrorType["biometryLockout"] = "biometryLockout";
51
+ BiometryErrorType["biometryNotAvailable"] = "biometryNotAvailable";
52
+ BiometryErrorType["biometryNotEnrolled"] = "biometryNotEnrolled";
53
+ BiometryErrorType["noDeviceCredential"] = "noDeviceCredential";
58
54
  })(exports.BiometryErrorType || (exports.BiometryErrorType = {}));
59
55
  class BiometryError {
60
56
  constructor(message, code) {
61
57
  this.message = message;
62
- this.code = exports.BiometryErrorType[code];
58
+ this.code = code;
63
59
  }
64
60
  }
65
61
 
@@ -69,7 +65,7 @@ var capacitorBiometricAuth = (function (exports, core, app) {
69
65
  [exports.BiometryType.faceId]: 'Face ID',
70
66
  [exports.BiometryType.fingerprintAuthentication]: 'Fingerprint Authentication',
71
67
  [exports.BiometryType.faceAuthentication]: 'Face Authentication',
72
- [exports.BiometryType.irisAuthentication]: 'Iris Authentication'
68
+ [exports.BiometryType.irisAuthentication]: 'Iris Authentication',
73
69
  };
74
70
  /**
75
71
  * Return a human-readable name for a BiometryType.
@@ -79,11 +75,10 @@ var capacitorBiometricAuth = (function (exports, core, app) {
79
75
  return kBiometryTypeNameMap[type] || '';
80
76
  }
81
77
 
82
- console.log(`loaded ${info.name} v${info.version}`);
83
78
  const proxy = core.registerPlugin('BiometricAuthNative', {
84
79
  web: async () => Promise.resolve().then(function () { return web; }).then((module) => new module.BiometricAuthWeb()),
85
80
  ios: async () => Promise.resolve().then(function () { return native; }).then((module) => new module.BiometricAuthNative(proxy)),
86
- android: async () => Promise.resolve().then(function () { return native; }).then((module) => new module.BiometricAuthNative(proxy))
81
+ android: async () => Promise.resolve().then(function () { return native; }).then((module) => new module.BiometricAuthNative(proxy)),
87
82
  });
88
83
 
89
84
  // eslint-disable-next-line import/prefer-default-export
@@ -111,7 +106,8 @@ var capacitorBiometricAuth = (function (exports, core, app) {
111
106
  return Promise.resolve({
112
107
  isAvailable: this.biometryType !== exports.BiometryType.none,
113
108
  biometryType: this.biometryType,
114
- reason: ''
109
+ reason: '',
110
+ code: exports.BiometryErrorType.none,
115
111
  });
116
112
  }
117
113
  async authenticate(options) {
@@ -163,7 +159,8 @@ var capacitorBiometricAuth = (function (exports, core, app) {
163
159
  return Promise.resolve({
164
160
  isAvailable: true,
165
161
  biometryType: exports.BiometryType.none,
166
- reason: ''
162
+ reason: '',
163
+ code: exports.BiometryErrorType.none,
167
164
  });
168
165
  }
169
166
  // eslint-disable-next-line @typescript-eslint/no-unused-vars,@typescript-eslint/no-empty-function
@@ -185,8 +182,6 @@ var capacitorBiometricAuth = (function (exports, core, app) {
185
182
  exports.BiometryError = BiometryError;
186
183
  exports.getBiometryName = getBiometryName;
187
184
 
188
- Object.defineProperty(exports, '__esModule', { value: true });
189
-
190
185
  return exports;
191
186
 
192
187
  })({}, capacitorExports, app);
@@ -1,8 +1,6 @@
1
1
  #import <Foundation/Foundation.h>
2
2
  #import <Capacitor/Capacitor.h>
3
3
 
4
- // Generated by @aparajita/capacitor-native-decorator/make-ios-plugin
5
-
6
4
  CAP_PLUGIN(BiometricAuthNative, "BiometricAuthNative",
7
5
  CAP_PLUGIN_METHOD(checkBiometry, CAPPluginReturnPromise);
8
6
  CAP_PLUGIN_METHOD(authenticate, CAPPluginReturnPromise);
@@ -7,18 +7,18 @@ private let kMissingFaceIDUsageEntry = "The device supports Face ID, but NSFaceI
7
7
 
8
8
  @objc(BiometricAuthNative)
9
9
  public class BiometricAuthNative: CAPPlugin {
10
- let biometryErrorCodeMap: [LAError.Code: String] = [
11
- .appCancel: "appCancel",
12
- .authenticationFailed: "authenticationFailed",
13
- .invalidContext: "invalidContext",
14
- .notInteractive: "notInteractive",
15
- .passcodeNotSet: "passcodeNotSet",
16
- .systemCancel: "systemCancel",
17
- .userCancel: "userCancel",
18
- .userFallback: "userFallback",
19
- .biometryLockout: "biometryLockout",
20
- .biometryNotAvailable: "biometryNotAvailable",
21
- .biometryNotEnrolled: "biometryNotEnrolled"
10
+ let biometryErrorCodeMap: [Int: String] = [
11
+ LAError.appCancel.rawValue: "appCancel",
12
+ LAError.authenticationFailed.rawValue: "authenticationFailed",
13
+ LAError.invalidContext.rawValue: "invalidContext",
14
+ LAError.notInteractive.rawValue: "notInteractive",
15
+ LAError.passcodeNotSet.rawValue: "passcodeNotSet",
16
+ LAError.systemCancel.rawValue: "systemCancel",
17
+ LAError.userCancel.rawValue: "userCancel",
18
+ LAError.userFallback.rawValue: "userFallback",
19
+ LAError.biometryLockout.rawValue: "biometryLockout",
20
+ LAError.biometryNotAvailable.rawValue: "biometryNotAvailable",
21
+ LAError.biometryNotEnrolled.rawValue: "biometryNotEnrolled",
22
22
  ]
23
23
 
24
24
  var canEvaluatePolicy = true
@@ -31,6 +31,7 @@ public class BiometricAuthNative: CAPPlugin {
31
31
  var error: NSError?
32
32
  var available = context.canEvaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, error: &error)
33
33
  var reason = ""
34
+ var errorCode = ""
34
35
 
35
36
  if available, context.biometryType == .faceID {
36
37
  // The system may report that biometry is available, but if the type is Face ID
@@ -42,6 +43,7 @@ public class BiometricAuthNative: CAPPlugin {
42
43
  available = false
43
44
  canEvaluatePolicy = false
44
45
  reason = kMissingFaceIDUsageEntry
46
+ errorCode = biometryErrorCodeMap[LAError.biometryNotAvailable.rawValue] ?? ""
45
47
  }
46
48
  } else if !available,
47
49
  let error = error {
@@ -51,12 +53,15 @@ public class BiometricAuthNative: CAPPlugin {
51
53
  if let failureReason = error.localizedFailureReason {
52
54
  reason = "\(reason): \(failureReason)"
53
55
  }
56
+
57
+ errorCode = biometryErrorCodeMap[error.code] ?? biometryErrorCodeMap[LAError.biometryNotAvailable.rawValue] ?? ""
54
58
  }
55
59
 
56
60
  call.resolve([
57
61
  "isAvailable": available,
58
62
  "biometryType": context.biometryType.rawValue,
59
- "reason": reason
63
+ "reason": reason,
64
+ "code": errorCode
60
65
  ])
61
66
  }
62
67
 
@@ -72,7 +77,7 @@ public class BiometricAuthNative: CAPPlugin {
72
77
  guard canEvaluatePolicy else {
73
78
  call.reject(
74
79
  kMissingFaceIDUsageEntry,
75
- biometryErrorCodeMap[.biometryNotAvailable]
80
+ biometryErrorCodeMap[LAError.biometryNotAvailable.rawValue]
76
81
  )
77
82
 
78
83
  return
@@ -111,10 +116,10 @@ public class BiometricAuthNative: CAPPlugin {
111
116
  call.resolve()
112
117
  } else {
113
118
  if let policyError = error as? LAError {
114
- let code = self.biometryErrorCodeMap[policyError.code]
119
+ let code = self.biometryErrorCodeMap[policyError.code.rawValue]
115
120
  call.reject(policyError.localizedDescription, code)
116
121
  } else {
117
- call.reject("An unknown error occurred.", self.biometryErrorCodeMap[.authenticationFailed])
122
+ call.reject("An unknown error occurred.", self.biometryErrorCodeMap[LAError.authenticationFailed.rawValue])
118
123
  }
119
124
  }
120
125
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aparajita/capacitor-biometric-auth",
3
- "version": "3.1.4",
3
+ "version": "5.0.0",
4
4
  "description": "Provides access to the native biometric auth APIs for Capacitor apps",
5
5
  "author": "Aparajita Fishman",
6
6
  "license": "MIT",
@@ -56,46 +56,44 @@
56
56
  "@aparajita/eslint-config-base": "^1.1.5",
57
57
  "@aparajita/prettier-config": "^1.0.0",
58
58
  "@aparajita/swiftly": "^1.0.4",
59
- "@capacitor/cli": "^4.0.1",
60
- "@commitlint/cli": "^17.0.3",
61
- "@commitlint/config-conventional": "^17.0.3",
59
+ "@capacitor/cli": "^5.0.5",
60
+ "@commitlint/cli": "^17.6.5",
61
+ "@commitlint/config-conventional": "^17.6.5",
62
62
  "@ionic/swiftlint-config": "^1.1.2",
63
- "@rollup/plugin-json": "^4.1.0",
64
- "@types/node": "^18.6.5",
65
- "@typescript-eslint/eslint-plugin": "^5.33.0",
66
- "@typescript-eslint/parser": "^5.33.0",
67
- "commit-and-tag-version": "^10.0.1",
68
- "eslint": "^8.21.0",
69
- "eslint-config-prettier": "^8.5.0",
70
- "eslint-config-standard": "^17.0.0",
71
- "eslint-import-resolver-typescript": "^3.4.0",
72
- "eslint-plugin-import": "^2.26.0",
73
- "eslint-plugin-n": "^15.2.4",
63
+ "@rollup/plugin-json": "^6.0.0",
64
+ "@types/node": "^20.3.1",
65
+ "@typescript-eslint/eslint-plugin": "^5.59.11",
66
+ "@typescript-eslint/parser": "^5.59.11",
67
+ "commit-and-tag-version": "^11.2.1",
68
+ "eslint": "^8.42.0",
69
+ "eslint-config-prettier": "^8.8.0",
70
+ "eslint-config-standard": "^17.1.0",
71
+ "eslint-import-resolver-typescript": "^3.5.5",
72
+ "eslint-plugin-import": "^2.27.5",
73
+ "eslint-plugin-n": "^16.0.0",
74
74
  "eslint-plugin-prettier": "^4.2.1",
75
- "eslint-plugin-promise": "^6.0.0",
76
- "husky": "^8.0.1",
77
- "nodemon": "^2.0.19",
78
- "prettier": "^2.7.1",
79
- "prettier-plugin-java": "^1.6.2",
80
- "rimraf": "^3.0.2",
81
- "rollup": "^2.77.2",
82
- "swiftlint": "^1.0.1",
83
- "typescript": "~4.7.4"
75
+ "eslint-plugin-promise": "^6.1.1",
76
+ "nodemon": "^2.0.22",
77
+ "prettier": "^2.8.8",
78
+ "prettier-plugin-java": "^2.1.0",
79
+ "rimraf": "^5.0.1",
80
+ "rollup": "^3.25.1",
81
+ "swiftlint": "^1.0.2",
82
+ "typescript": "~5.1.3"
84
83
  },
85
84
  "dependencies": {
86
- "@capacitor/android": "^4.0.1",
87
- "@capacitor/app": "^4.0.1",
88
- "@capacitor/core": "^4.0.1",
89
- "@capacitor/ios": "^4.0.1"
85
+ "@capacitor/android": "^5.0.5",
86
+ "@capacitor/app": "^5.0.3",
87
+ "@capacitor/core": "^5.0.5",
88
+ "@capacitor/ios": "^5.0.5"
90
89
  },
91
90
  "scripts": {
92
91
  "clean": "rimraf dist",
93
- "extract-info": "node scripts/extractPackageInfo.js",
94
92
  "lint.eslint": "eslint --fix --cache --ext .js,.cjs,.mjs,.ts --max-warnings 0",
95
93
  "lint.prettier": "prettier --write --cache --list-different",
96
94
  "lint.tsc": "tsc --noEmit",
97
95
  "lint": "pnpm lint.eslint . && pnpm lint.prettier . && pnpm lint.tsc",
98
- "prebuilder": "pnpm clean && pnpm extract-info",
96
+ "prebuilder": "pnpm clean",
99
97
  "builder": "tsc ${SOURCE_MAP:-} && rollup -c rollup.config.mjs",
100
98
  "prebuild": "pnpm lint",
101
99
  "build": "pnpm builder",
@@ -1,4 +0,0 @@
1
- {
2
- "name": "@aparajita/capacitor-biometric-auth",
3
- "version": "3.1.4"
4
- }