@aparajita/capacitor-biometric-auth 1.0.7 → 2.0.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/AparajitaCapacitorBiometricAuth.podspec +2 -2
- package/README.md +76 -62
- package/android/src/main/java/com/aparajita/capacitor/biometricauth/AuthActivity.java +123 -95
- package/android/src/main/java/com/aparajita/capacitor/biometricauth/BiometricAuth.java +262 -0
- package/android/src/main/java/com/aparajita/capacitor/biometricauth/BiometryResultType.java +3 -3
- package/dist/esm/definitions.d.ts +26 -33
- package/dist/esm/definitions.js +2 -2
- package/dist/esm/index.d.ts +4 -1
- package/dist/esm/index.js +17 -2
- package/dist/esm/package.json +113 -0
- package/dist/esm/web.d.ts +6 -6
- package/dist/esm/web.js +36 -29
- package/dist/plugin.cjs.js +172 -0
- package/dist/plugin.js +173 -0
- package/ios/Plugin/Plugin.m +3 -1
- package/ios/Plugin/Plugin.swift +6 -6
- package/package.json +76 -48
- package/CHANGELOG.md +0 -71
- package/android/gradle.properties +0 -21
- package/android/settings.gradle +0 -2
- package/android/src/main/java/com/aparajita/capacitor/biometricauth/WSBiometricAuth.java +0 -216
- package/ios/Podfile +0 -16
- package/ios/Podfile.lock +0 -22
package/dist/esm/web.js
CHANGED
|
@@ -1,30 +1,37 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
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
|
+
};
|
|
4
7
|
import { native } from '@aparajita/capacitor-native-decorator';
|
|
8
|
+
import { App } from '@capacitor/app';
|
|
9
|
+
import { WebPlugin } from '@capacitor/core';
|
|
10
|
+
import { BiometryError, BiometryErrorType, BiometryType, kPluginName } from './definitions';
|
|
5
11
|
const kBiometryTypeNameMap = {
|
|
6
12
|
[BiometryType.none]: '',
|
|
7
13
|
[BiometryType.touchId]: 'Touch ID',
|
|
8
14
|
[BiometryType.faceId]: 'Face ID',
|
|
9
15
|
[BiometryType.fingerprintAuthentication]: 'Fingerprint Authentication',
|
|
10
16
|
[BiometryType.faceAuthentication]: 'Face Authentication',
|
|
11
|
-
[BiometryType.irisAuthentication]: 'Iris Authentication'
|
|
17
|
+
[BiometryType.irisAuthentication]: 'Iris Authentication'
|
|
12
18
|
};
|
|
13
|
-
export class
|
|
19
|
+
export class BiometricAuth extends WebPlugin {
|
|
14
20
|
constructor() {
|
|
15
|
-
super(
|
|
16
|
-
name: 'WSBiometricAuth',
|
|
17
|
-
platforms: ['web', 'ios', 'android'],
|
|
18
|
-
});
|
|
21
|
+
super(...arguments);
|
|
19
22
|
this.biometryType = BiometryType.none;
|
|
20
|
-
|
|
23
|
+
}
|
|
24
|
+
getRegisteredPluginName() {
|
|
25
|
+
return kPluginName;
|
|
21
26
|
}
|
|
22
27
|
setBiometryType(type) {
|
|
23
28
|
if (typeof type === 'undefined') {
|
|
24
29
|
return;
|
|
25
30
|
}
|
|
26
31
|
if (typeof type === 'string') {
|
|
27
|
-
|
|
32
|
+
// eslint-disable-next-line no-prototype-builtins
|
|
33
|
+
if (BiometryType.hasOwnProperty(type)) {
|
|
34
|
+
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
28
35
|
this.biometryType = BiometryType[type];
|
|
29
36
|
}
|
|
30
37
|
}
|
|
@@ -32,17 +39,19 @@ export class WSBiometricAuthWeb extends WebPlugin {
|
|
|
32
39
|
this.biometryType = type;
|
|
33
40
|
}
|
|
34
41
|
}
|
|
35
|
-
checkBiometry() {
|
|
42
|
+
async checkBiometry() {
|
|
36
43
|
return Promise.resolve({
|
|
37
44
|
isAvailable: this.biometryType !== BiometryType.none,
|
|
38
45
|
biometryType: this.biometryType,
|
|
39
|
-
reason: ''
|
|
46
|
+
reason: ''
|
|
40
47
|
});
|
|
41
48
|
}
|
|
42
|
-
authenticate(options) {
|
|
49
|
+
async authenticate(options) {
|
|
43
50
|
return this.checkBiometry().then(({ isAvailable, biometryType }) => {
|
|
44
51
|
if (isAvailable) {
|
|
45
|
-
if (
|
|
52
|
+
if (
|
|
53
|
+
// eslint-disable-next-line no-alert
|
|
54
|
+
confirm((options === null || options === void 0 ? void 0 : options.reason) ||
|
|
46
55
|
`Authenticate with ${kBiometryTypeNameMap[biometryType]}?`)) {
|
|
47
56
|
return;
|
|
48
57
|
}
|
|
@@ -52,23 +61,25 @@ export class WSBiometricAuthWeb extends WebPlugin {
|
|
|
52
61
|
});
|
|
53
62
|
}
|
|
54
63
|
addResumeListener(listener) {
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
const info = await this.checkBiometry();
|
|
64
|
+
return App.addListener('appStateChange', ({ isActive }) => {
|
|
65
|
+
if (isActive) {
|
|
66
|
+
this.checkBiometry()
|
|
67
|
+
.then((info) => {
|
|
60
68
|
listener(info);
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
|
|
69
|
+
})
|
|
70
|
+
.catch((error) => {
|
|
71
|
+
console.error(error.message);
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
});
|
|
64
75
|
}
|
|
65
76
|
}
|
|
66
77
|
__decorate([
|
|
67
78
|
native()
|
|
68
|
-
],
|
|
79
|
+
], BiometricAuth.prototype, "checkBiometry", null);
|
|
69
80
|
__decorate([
|
|
70
81
|
native()
|
|
71
|
-
],
|
|
82
|
+
], BiometricAuth.prototype, "authenticate", null);
|
|
72
83
|
/**
|
|
73
84
|
* Return a human-readable name for a BiometryType.
|
|
74
85
|
*
|
|
@@ -78,7 +89,3 @@ __decorate([
|
|
|
78
89
|
export function getBiometryName(type) {
|
|
79
90
|
return kBiometryTypeNameMap[type] || '';
|
|
80
91
|
}
|
|
81
|
-
const WSBiometricAuth = new WSBiometricAuthWeb();
|
|
82
|
-
export { WSBiometricAuth };
|
|
83
|
-
registerWebPlugin(WSBiometricAuth);
|
|
84
|
-
//# sourceMappingURL=web.js.map
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
|
+
|
|
5
|
+
var core = require('@capacitor/core');
|
|
6
|
+
var capacitorNativeDecorator = require('@aparajita/capacitor-native-decorator');
|
|
7
|
+
var app = require('@capacitor/app');
|
|
8
|
+
|
|
9
|
+
exports.BiometryType = void 0;
|
|
10
|
+
(function (BiometryType) {
|
|
11
|
+
/**
|
|
12
|
+
* No biometry is available
|
|
13
|
+
*/
|
|
14
|
+
BiometryType[BiometryType["none"] = 0] = "none";
|
|
15
|
+
/**
|
|
16
|
+
* iOS Touch ID is available
|
|
17
|
+
*/
|
|
18
|
+
BiometryType[BiometryType["touchId"] = 1] = "touchId";
|
|
19
|
+
/**
|
|
20
|
+
* iOS Face ID is available
|
|
21
|
+
*/
|
|
22
|
+
BiometryType[BiometryType["faceId"] = 2] = "faceId";
|
|
23
|
+
/**
|
|
24
|
+
* Android fingerprint authentication is available
|
|
25
|
+
*/
|
|
26
|
+
BiometryType[BiometryType["fingerprintAuthentication"] = 3] = "fingerprintAuthentication";
|
|
27
|
+
/**
|
|
28
|
+
* Android face authentication is available
|
|
29
|
+
*/
|
|
30
|
+
BiometryType[BiometryType["faceAuthentication"] = 4] = "faceAuthentication";
|
|
31
|
+
/**
|
|
32
|
+
* Android iris authentication is available
|
|
33
|
+
*/
|
|
34
|
+
BiometryType[BiometryType["irisAuthentication"] = 5] = "irisAuthentication";
|
|
35
|
+
})(exports.BiometryType || (exports.BiometryType = {}));
|
|
36
|
+
/**
|
|
37
|
+
* If the `authenticate()` method throws an exception, the error object
|
|
38
|
+
* contains a .code property which will contain one of these strings,
|
|
39
|
+
* indicating what the error was.
|
|
40
|
+
*
|
|
41
|
+
* See https://developer.apple.com/documentation/localauthentication/laerror
|
|
42
|
+
* for a description of each error code.
|
|
43
|
+
*/
|
|
44
|
+
exports.BiometryErrorType = void 0;
|
|
45
|
+
(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";
|
|
58
|
+
})(exports.BiometryErrorType || (exports.BiometryErrorType = {}));
|
|
59
|
+
class BiometryError {
|
|
60
|
+
constructor(message, code) {
|
|
61
|
+
this.message = message;
|
|
62
|
+
this.code = exports.BiometryErrorType[code];
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
const kPluginName = 'BiometricAuth';
|
|
66
|
+
|
|
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;
|
|
74
|
+
};
|
|
75
|
+
const kBiometryTypeNameMap = {
|
|
76
|
+
[exports.BiometryType.none]: '',
|
|
77
|
+
[exports.BiometryType.touchId]: 'Touch ID',
|
|
78
|
+
[exports.BiometryType.faceId]: 'Face ID',
|
|
79
|
+
[exports.BiometryType.fingerprintAuthentication]: 'Fingerprint Authentication',
|
|
80
|
+
[exports.BiometryType.faceAuthentication]: 'Face Authentication',
|
|
81
|
+
[exports.BiometryType.irisAuthentication]: 'Iris Authentication'
|
|
82
|
+
};
|
|
83
|
+
class BiometricAuth extends core.WebPlugin {
|
|
84
|
+
constructor() {
|
|
85
|
+
super(...arguments);
|
|
86
|
+
this.biometryType = exports.BiometryType.none;
|
|
87
|
+
}
|
|
88
|
+
getRegisteredPluginName() {
|
|
89
|
+
return kPluginName;
|
|
90
|
+
}
|
|
91
|
+
setBiometryType(type) {
|
|
92
|
+
if (typeof type === 'undefined') {
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
if (typeof type === 'string') {
|
|
96
|
+
// eslint-disable-next-line no-prototype-builtins
|
|
97
|
+
if (exports.BiometryType.hasOwnProperty(type)) {
|
|
98
|
+
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
99
|
+
this.biometryType = exports.BiometryType[type];
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
else {
|
|
103
|
+
this.biometryType = type;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
async checkBiometry() {
|
|
107
|
+
return Promise.resolve({
|
|
108
|
+
isAvailable: this.biometryType !== exports.BiometryType.none,
|
|
109
|
+
biometryType: this.biometryType,
|
|
110
|
+
reason: ''
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
async authenticate(options) {
|
|
114
|
+
return this.checkBiometry().then(({ isAvailable, biometryType }) => {
|
|
115
|
+
if (isAvailable) {
|
|
116
|
+
if (
|
|
117
|
+
// eslint-disable-next-line no-alert
|
|
118
|
+
confirm((options === null || options === void 0 ? void 0 : options.reason) ||
|
|
119
|
+
`Authenticate with ${kBiometryTypeNameMap[biometryType]}?`)) {
|
|
120
|
+
return;
|
|
121
|
+
}
|
|
122
|
+
throw new BiometryError('User cancelled', exports.BiometryErrorType.userCancel);
|
|
123
|
+
}
|
|
124
|
+
throw new BiometryError('Biometry not available', exports.BiometryErrorType.biometryNotAvailable);
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
addResumeListener(listener) {
|
|
128
|
+
return app.App.addListener('appStateChange', ({ isActive }) => {
|
|
129
|
+
if (isActive) {
|
|
130
|
+
this.checkBiometry()
|
|
131
|
+
.then((info) => {
|
|
132
|
+
listener(info);
|
|
133
|
+
})
|
|
134
|
+
.catch((error) => {
|
|
135
|
+
console.error(error.message);
|
|
136
|
+
});
|
|
137
|
+
}
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
__decorate([
|
|
142
|
+
capacitorNativeDecorator.native()
|
|
143
|
+
], BiometricAuth.prototype, "checkBiometry", null);
|
|
144
|
+
__decorate([
|
|
145
|
+
capacitorNativeDecorator.native()
|
|
146
|
+
], BiometricAuth.prototype, "authenticate", null);
|
|
147
|
+
/**
|
|
148
|
+
* Return a human-readable name for a BiometryType.
|
|
149
|
+
*
|
|
150
|
+
* @param {BiometryType} type
|
|
151
|
+
* @returns {string}
|
|
152
|
+
*/
|
|
153
|
+
function getBiometryName(type) {
|
|
154
|
+
return kBiometryTypeNameMap[type] || '';
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
console.log(`loaded ${name}`);
|
|
158
|
+
// Because we are using @aparajita/capacitor-native-decorator,
|
|
159
|
+
// we have one version of the TS code to rule them all, and there
|
|
160
|
+
// is no need to lazy load. 😁
|
|
161
|
+
const plugin = new BiometricAuth();
|
|
162
|
+
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
163
|
+
const biometricAuth = core.registerPlugin(kPluginName, {
|
|
164
|
+
web: plugin,
|
|
165
|
+
ios: plugin,
|
|
166
|
+
android: plugin
|
|
167
|
+
});
|
|
168
|
+
|
|
169
|
+
exports.BiometricAuth = biometricAuth;
|
|
170
|
+
exports.BiometryError = BiometryError;
|
|
171
|
+
exports.getBiometryName = getBiometryName;
|
|
172
|
+
exports.kPluginName = kPluginName;
|
package/dist/plugin.js
ADDED
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
var capacitorBiometricAuth = (function (exports, core, capacitorNativeDecorator, app) {
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
exports.BiometryType = void 0;
|
|
5
|
+
(function (BiometryType) {
|
|
6
|
+
/**
|
|
7
|
+
* No biometry is available
|
|
8
|
+
*/
|
|
9
|
+
BiometryType[BiometryType["none"] = 0] = "none";
|
|
10
|
+
/**
|
|
11
|
+
* iOS Touch ID is available
|
|
12
|
+
*/
|
|
13
|
+
BiometryType[BiometryType["touchId"] = 1] = "touchId";
|
|
14
|
+
/**
|
|
15
|
+
* iOS Face ID is available
|
|
16
|
+
*/
|
|
17
|
+
BiometryType[BiometryType["faceId"] = 2] = "faceId";
|
|
18
|
+
/**
|
|
19
|
+
* Android fingerprint authentication is available
|
|
20
|
+
*/
|
|
21
|
+
BiometryType[BiometryType["fingerprintAuthentication"] = 3] = "fingerprintAuthentication";
|
|
22
|
+
/**
|
|
23
|
+
* Android face authentication is available
|
|
24
|
+
*/
|
|
25
|
+
BiometryType[BiometryType["faceAuthentication"] = 4] = "faceAuthentication";
|
|
26
|
+
/**
|
|
27
|
+
* Android iris authentication is available
|
|
28
|
+
*/
|
|
29
|
+
BiometryType[BiometryType["irisAuthentication"] = 5] = "irisAuthentication";
|
|
30
|
+
})(exports.BiometryType || (exports.BiometryType = {}));
|
|
31
|
+
/**
|
|
32
|
+
* If the `authenticate()` method throws an exception, the error object
|
|
33
|
+
* contains a .code property which will contain one of these strings,
|
|
34
|
+
* indicating what the error was.
|
|
35
|
+
*
|
|
36
|
+
* See https://developer.apple.com/documentation/localauthentication/laerror
|
|
37
|
+
* for a description of each error code.
|
|
38
|
+
*/
|
|
39
|
+
exports.BiometryErrorType = void 0;
|
|
40
|
+
(function (BiometryErrorType) {
|
|
41
|
+
BiometryErrorType[BiometryErrorType["appCancel"] = 0] = "appCancel";
|
|
42
|
+
BiometryErrorType[BiometryErrorType["authenticationFailed"] = 1] = "authenticationFailed";
|
|
43
|
+
BiometryErrorType[BiometryErrorType["invalidContext"] = 2] = "invalidContext";
|
|
44
|
+
BiometryErrorType[BiometryErrorType["notInteractive"] = 3] = "notInteractive";
|
|
45
|
+
BiometryErrorType[BiometryErrorType["passcodeNotSet"] = 4] = "passcodeNotSet";
|
|
46
|
+
BiometryErrorType[BiometryErrorType["systemCancel"] = 5] = "systemCancel";
|
|
47
|
+
BiometryErrorType[BiometryErrorType["userCancel"] = 6] = "userCancel";
|
|
48
|
+
BiometryErrorType[BiometryErrorType["userFallback"] = 7] = "userFallback";
|
|
49
|
+
BiometryErrorType[BiometryErrorType["biometryLockout"] = 8] = "biometryLockout";
|
|
50
|
+
BiometryErrorType[BiometryErrorType["biometryNotAvailable"] = 9] = "biometryNotAvailable";
|
|
51
|
+
BiometryErrorType[BiometryErrorType["biometryNotEnrolled"] = 10] = "biometryNotEnrolled";
|
|
52
|
+
BiometryErrorType[BiometryErrorType["noDeviceCredential"] = 11] = "noDeviceCredential";
|
|
53
|
+
})(exports.BiometryErrorType || (exports.BiometryErrorType = {}));
|
|
54
|
+
class BiometryError {
|
|
55
|
+
constructor(message, code) {
|
|
56
|
+
this.message = message;
|
|
57
|
+
this.code = exports.BiometryErrorType[code];
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
const kPluginName = 'BiometricAuth';
|
|
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;
|
|
69
|
+
};
|
|
70
|
+
const kBiometryTypeNameMap = {
|
|
71
|
+
[exports.BiometryType.none]: '',
|
|
72
|
+
[exports.BiometryType.touchId]: 'Touch ID',
|
|
73
|
+
[exports.BiometryType.faceId]: 'Face ID',
|
|
74
|
+
[exports.BiometryType.fingerprintAuthentication]: 'Fingerprint Authentication',
|
|
75
|
+
[exports.BiometryType.faceAuthentication]: 'Face Authentication',
|
|
76
|
+
[exports.BiometryType.irisAuthentication]: 'Iris Authentication'
|
|
77
|
+
};
|
|
78
|
+
class BiometricAuth extends core.WebPlugin {
|
|
79
|
+
constructor() {
|
|
80
|
+
super(...arguments);
|
|
81
|
+
this.biometryType = exports.BiometryType.none;
|
|
82
|
+
}
|
|
83
|
+
getRegisteredPluginName() {
|
|
84
|
+
return kPluginName;
|
|
85
|
+
}
|
|
86
|
+
setBiometryType(type) {
|
|
87
|
+
if (typeof type === 'undefined') {
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
if (typeof type === 'string') {
|
|
91
|
+
// eslint-disable-next-line no-prototype-builtins
|
|
92
|
+
if (exports.BiometryType.hasOwnProperty(type)) {
|
|
93
|
+
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
94
|
+
this.biometryType = exports.BiometryType[type];
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
else {
|
|
98
|
+
this.biometryType = type;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
async checkBiometry() {
|
|
102
|
+
return Promise.resolve({
|
|
103
|
+
isAvailable: this.biometryType !== exports.BiometryType.none,
|
|
104
|
+
biometryType: this.biometryType,
|
|
105
|
+
reason: ''
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
async authenticate(options) {
|
|
109
|
+
return this.checkBiometry().then(({ isAvailable, biometryType }) => {
|
|
110
|
+
if (isAvailable) {
|
|
111
|
+
if (
|
|
112
|
+
// eslint-disable-next-line no-alert
|
|
113
|
+
confirm((options === null || options === void 0 ? void 0 : options.reason) ||
|
|
114
|
+
`Authenticate with ${kBiometryTypeNameMap[biometryType]}?`)) {
|
|
115
|
+
return;
|
|
116
|
+
}
|
|
117
|
+
throw new BiometryError('User cancelled', exports.BiometryErrorType.userCancel);
|
|
118
|
+
}
|
|
119
|
+
throw new BiometryError('Biometry not available', exports.BiometryErrorType.biometryNotAvailable);
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
addResumeListener(listener) {
|
|
123
|
+
return app.App.addListener('appStateChange', ({ isActive }) => {
|
|
124
|
+
if (isActive) {
|
|
125
|
+
this.checkBiometry()
|
|
126
|
+
.then((info) => {
|
|
127
|
+
listener(info);
|
|
128
|
+
})
|
|
129
|
+
.catch((error) => {
|
|
130
|
+
console.error(error.message);
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
__decorate([
|
|
137
|
+
capacitorNativeDecorator.native()
|
|
138
|
+
], BiometricAuth.prototype, "checkBiometry", null);
|
|
139
|
+
__decorate([
|
|
140
|
+
capacitorNativeDecorator.native()
|
|
141
|
+
], BiometricAuth.prototype, "authenticate", null);
|
|
142
|
+
/**
|
|
143
|
+
* Return a human-readable name for a BiometryType.
|
|
144
|
+
*
|
|
145
|
+
* @param {BiometryType} type
|
|
146
|
+
* @returns {string}
|
|
147
|
+
*/
|
|
148
|
+
function getBiometryName(type) {
|
|
149
|
+
return kBiometryTypeNameMap[type] || '';
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
console.log(`loaded ${name}`);
|
|
153
|
+
// Because we are using @aparajita/capacitor-native-decorator,
|
|
154
|
+
// we have one version of the TS code to rule them all, and there
|
|
155
|
+
// is no need to lazy load. 😁
|
|
156
|
+
const plugin = new BiometricAuth();
|
|
157
|
+
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
158
|
+
const biometricAuth = core.registerPlugin(kPluginName, {
|
|
159
|
+
web: plugin,
|
|
160
|
+
ios: plugin,
|
|
161
|
+
android: plugin
|
|
162
|
+
});
|
|
163
|
+
|
|
164
|
+
exports.BiometricAuth = biometricAuth;
|
|
165
|
+
exports.BiometryError = BiometryError;
|
|
166
|
+
exports.getBiometryName = getBiometryName;
|
|
167
|
+
exports.kPluginName = kPluginName;
|
|
168
|
+
|
|
169
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
170
|
+
|
|
171
|
+
return exports;
|
|
172
|
+
|
|
173
|
+
})({}, capacitorExports, capacitorNativeDecorator, app);
|
package/ios/Plugin/Plugin.m
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
#import <Foundation/Foundation.h>
|
|
2
2
|
#import <Capacitor/Capacitor.h>
|
|
3
3
|
|
|
4
|
-
|
|
4
|
+
// Generated by @aparajita/capacitor-native-decorator/make-ios-plugin
|
|
5
|
+
|
|
6
|
+
CAP_PLUGIN(BiometricAuth, "BiometricAuth",
|
|
5
7
|
CAP_PLUGIN_METHOD(checkBiometry, CAPPluginReturnPromise);
|
|
6
8
|
CAP_PLUGIN_METHOD(authenticate, CAPPluginReturnPromise);
|
|
7
9
|
)
|
package/ios/Plugin/Plugin.swift
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
import Foundation
|
|
2
1
|
import Capacitor
|
|
2
|
+
import Foundation
|
|
3
3
|
import LocalAuthentication
|
|
4
4
|
|
|
5
5
|
private let kReason = "reason"
|
|
6
6
|
private let kMissingFaceIDUsageEntry = "The device supports Face ID, but NSFaceIDUsageDescription is not in Info.plist."
|
|
7
7
|
|
|
8
|
-
@objc(
|
|
9
|
-
public class
|
|
8
|
+
@objc(BiometricAuth)
|
|
9
|
+
public class BiometricAuth: CAPPlugin {
|
|
10
10
|
let biometryErrorCodeMap: [LAError.Code: String] = [
|
|
11
11
|
.appCancel: "appCancel",
|
|
12
12
|
.authenticationFailed: "authenticationFailed",
|
|
@@ -32,7 +32,7 @@ public class WSBiometricAuth: CAPPlugin {
|
|
|
32
32
|
var available = context.canEvaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, error: &error)
|
|
33
33
|
var reason = ""
|
|
34
34
|
|
|
35
|
-
if available
|
|
35
|
+
if available, context.biometryType == .faceID {
|
|
36
36
|
// The system may report that biometry is available, but if the type is Face ID
|
|
37
37
|
// and the developer forgot to add NSFaceIDUsageDescription to Info.plist,
|
|
38
38
|
// calls to evaluatePolicy() will crash.
|
|
@@ -44,7 +44,7 @@ public class WSBiometricAuth: CAPPlugin {
|
|
|
44
44
|
reason = kMissingFaceIDUsageEntry
|
|
45
45
|
}
|
|
46
46
|
} else if !available,
|
|
47
|
-
|
|
47
|
+
let error = error {
|
|
48
48
|
// If we get a reason from the system, return it
|
|
49
49
|
reason = error.localizedDescription
|
|
50
50
|
|
|
@@ -106,7 +106,7 @@ public class WSBiometricAuth: CAPPlugin {
|
|
|
106
106
|
context.localizedFallbackTitle = nil
|
|
107
107
|
}
|
|
108
108
|
|
|
109
|
-
context.evaluatePolicy(policy, localizedReason: reason) {
|
|
109
|
+
context.evaluatePolicy(policy, localizedReason: reason) { success, error in
|
|
110
110
|
if success {
|
|
111
111
|
call.resolve()
|
|
112
112
|
} else {
|
package/package.json
CHANGED
|
@@ -1,52 +1,23 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aparajita/capacitor-biometric-auth",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.2",
|
|
4
4
|
"description": "Provides access to the native biometric auth APIs for Capacitor apps",
|
|
5
|
-
"main": "dist/esm/index.js",
|
|
6
|
-
"module": "dist/esm/index.js",
|
|
7
|
-
"types": "dist/esm/index.d.ts",
|
|
8
|
-
"scripts": {
|
|
9
|
-
"clean": "rimraf ./dist",
|
|
10
|
-
"build": "npm run clean && tsc && rollup -c rollup.config.js && make-ios-plugin",
|
|
11
|
-
"watch": "nodemon -w ./src -w tsconfig.json -w rollup.config.js --exec 'npm run build --silent' -e ts",
|
|
12
|
-
"lint": "npm run prettier && npm run swiftlint",
|
|
13
|
-
"lint.fix": "npm run prettier.fix && npm run swiftlint.fix",
|
|
14
|
-
"prettier": "prettier --check --plugin=./node_modules/prettier-plugin-java \"**/*.{css,html,ts,js,java}\"",
|
|
15
|
-
"prettier.fix": "prettier --write --check --plugin=./node_modules/prettier-plugin-java \"**/*.{css,html,ts,js,java}\"",
|
|
16
|
-
"swiftlint": "cd ios; node-swiftlint; cd ..",
|
|
17
|
-
"swiftlint.fix": "cd ios; node-swiftlint autocorrect; cd ..",
|
|
18
|
-
"docgen": "docgen --api WSBiometricAuthPlugin --output-readme README.md",
|
|
19
|
-
"release": "standard-version",
|
|
20
|
-
"push": "git push --follow-tags origin main && npm publish"
|
|
21
|
-
},
|
|
22
5
|
"author": "Aparajita Fishman",
|
|
23
6
|
"license": "MIT",
|
|
24
|
-
"
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
"
|
|
30
|
-
"@types/node": "^14.14.37",
|
|
31
|
-
"nodemon": "^2.0.7",
|
|
32
|
-
"prettier": "^2.2.1",
|
|
33
|
-
"prettier-plugin-java": "^1.0.2",
|
|
34
|
-
"rimraf": "^3.0.2",
|
|
35
|
-
"rollup": "^2.44.0",
|
|
36
|
-
"swiftlint": "^1.0.1",
|
|
37
|
-
"typescript": "~4.2.3"
|
|
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"
|
|
38
13
|
},
|
|
39
14
|
"files": [
|
|
40
|
-
"
|
|
41
|
-
"dist/esm/*.js",
|
|
42
|
-
"ios/Plugin",
|
|
43
|
-
"ios/Podfile",
|
|
44
|
-
"ios/Podfile.lock",
|
|
45
|
-
"*.podspec",
|
|
15
|
+
"android/src/main/",
|
|
46
16
|
"android/build.gradle",
|
|
47
|
-
"
|
|
48
|
-
"
|
|
49
|
-
"
|
|
17
|
+
"dist/",
|
|
18
|
+
"ios/Plugin/",
|
|
19
|
+
"*.podspec",
|
|
20
|
+
"LICENSE"
|
|
50
21
|
],
|
|
51
22
|
"keywords": [
|
|
52
23
|
"capacitor",
|
|
@@ -66,7 +37,6 @@
|
|
|
66
37
|
"src": "android"
|
|
67
38
|
}
|
|
68
39
|
},
|
|
69
|
-
"prettier": "@ionic/prettier-config",
|
|
70
40
|
"swiftlint": "@ionic/swiftlint-config",
|
|
71
41
|
"repository": {
|
|
72
42
|
"type": "git",
|
|
@@ -75,11 +45,69 @@
|
|
|
75
45
|
"bugs": {
|
|
76
46
|
"url": "https://github.com/aparajita/capacitor-biometric-auth/issues"
|
|
77
47
|
},
|
|
48
|
+
"devDependencies": {
|
|
49
|
+
"@aparajita/capacitor-docgen": "github:aparajita/capacitor-docgen",
|
|
50
|
+
"@aparajita/capacitor-docgen-format": "github:aparajita/capacitor-docgen-format",
|
|
51
|
+
"@aparajita/eslint-config-base": "^1.1.2",
|
|
52
|
+
"@aparajita/prettier-config": "^1.0.0",
|
|
53
|
+
"@aparajita/swiftly": "^1.0.0",
|
|
54
|
+
"@capacitor/core": "^3.6.0",
|
|
55
|
+
"@ionic/swiftlint-config": "^1.1.2",
|
|
56
|
+
"@rollup/plugin-json": "^4.1.0",
|
|
57
|
+
"@types/node": "^18.0.0",
|
|
58
|
+
"@typescript-eslint/eslint-plugin": "^5.30.3",
|
|
59
|
+
"@typescript-eslint/parser": "^5.30.3",
|
|
60
|
+
"chalk": "^5.0.1",
|
|
61
|
+
"commit-and-tag-version": "^10.0.1",
|
|
62
|
+
"eslint": "^8.19.0",
|
|
63
|
+
"eslint-config-prettier": "^8.5.0",
|
|
64
|
+
"eslint-config-standard": "^17.0.0",
|
|
65
|
+
"eslint-import-resolver-typescript": "^3.1.4",
|
|
66
|
+
"eslint-plugin-import": "^2.26.0",
|
|
67
|
+
"eslint-plugin-n": "^15.2.3",
|
|
68
|
+
"eslint-plugin-prettier": "^4.2.1",
|
|
69
|
+
"eslint-plugin-promise": "^6.0.0",
|
|
70
|
+
"nodemon": "^2.0.18",
|
|
71
|
+
"prettier": "^2.7.1",
|
|
72
|
+
"prettier-plugin-java": "^1.6.2",
|
|
73
|
+
"rimraf": "^3.0.2",
|
|
74
|
+
"rollup": "^2.75.7",
|
|
75
|
+
"typescript": "~4.7.4"
|
|
76
|
+
},
|
|
78
77
|
"dependencies": {
|
|
79
|
-
"@aparajita/capacitor-native-decorator": "^
|
|
80
|
-
"@capacitor/android": "^
|
|
81
|
-
"@capacitor/
|
|
82
|
-
"@capacitor/ios": "^
|
|
83
|
-
|
|
78
|
+
"@aparajita/capacitor-native-decorator": "^2.0.3",
|
|
79
|
+
"@capacitor/android": "^3.6.0",
|
|
80
|
+
"@capacitor/app": "^1.1.1",
|
|
81
|
+
"@capacitor/ios": "^3.6.0"
|
|
82
|
+
},
|
|
83
|
+
"peerDependencies": {
|
|
84
|
+
"@capacitor/core": "^3.6.0"
|
|
85
|
+
},
|
|
86
|
+
"scripts": {
|
|
87
|
+
"clean": "rimraf ./dist",
|
|
88
|
+
"build": "pnpm check && pnpm build.only",
|
|
89
|
+
"build.dev": "pnpm check && pnpm build.only.dev",
|
|
90
|
+
"build.only": "pnpm clean && tsc $SOURCE_MAP && pnpm rollup && make-ios-plugin && pnpm docgen",
|
|
91
|
+
"build.only.dev": "SOURCE_MAP=--sourceMap pnpm build.only",
|
|
92
|
+
"rollup": "rollup -c rollup.config.mjs",
|
|
93
|
+
"watch": "nodemon -w ./src -w tsconfig.json -w rollup.config.mjs --exec 'pnpm build --silent' -e ts",
|
|
94
|
+
"lint": "eslint . && pnpm typecheck",
|
|
95
|
+
"lint.fix": "eslint --fix . && pnpm typecheck",
|
|
96
|
+
"typecheck": "tsc --noEmit",
|
|
97
|
+
"lint.swift": "pnpm swiftlint",
|
|
98
|
+
"prettier": "prettier --check \"**/*.{css,html,ts,js,json,java}\"",
|
|
99
|
+
"prettier.fix": "pnpm prettier --write",
|
|
100
|
+
"swiftlint": "swiftly ios",
|
|
101
|
+
"swiftlint.fix": "swiftly --fix ios",
|
|
102
|
+
"check": "pnpm lint && pnpm prettier && pnpm swiftlint",
|
|
103
|
+
"check.fix": "pnpm lint.fix && pnpm prettier.fix && pnpm swiftlint.fix",
|
|
104
|
+
"docgen": "docgen --api BiometricAuthPlugin --output-readme README.md && docgen-format",
|
|
105
|
+
"verify": "pnpm verify:ios && pnpm verify:android && pnpm verify:web",
|
|
106
|
+
"verify:ios": "cd ios && pod install && xcodebuild -workspace Plugin.xcworkspace -scheme Plugin && cd ..",
|
|
107
|
+
"verify:android": "cd android && ./gradlew clean build test && cd ..",
|
|
108
|
+
"verify:web": "pnpm build",
|
|
109
|
+
"push": "git push --follow-tags origin main",
|
|
110
|
+
"release.check": "commit-and-tag-version $VERSION --dry-run",
|
|
111
|
+
"release": "commit-and-tag-version $VERSION && pnpm push && pnpm publish"
|
|
84
112
|
}
|
|
85
|
-
}
|
|
113
|
+
}
|