@capgo/capacitor-native-biometric 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/CapgoCapacitorNativeBiometric.podspec +13 -0
- package/LICENSE +21 -0
- package/android/.gradle/8.0.2/checksums/checksums.lock +0 -0
- package/android/.gradle/8.0.2/dependencies-accessors/dependencies-accessors.lock +0 -0
- package/android/.gradle/8.0.2/dependencies-accessors/gc.properties +0 -0
- package/android/.gradle/8.0.2/executionHistory/executionHistory.bin +0 -0
- package/android/.gradle/8.0.2/executionHistory/executionHistory.lock +0 -0
- package/android/.gradle/8.0.2/fileChanges/last-build.bin +0 -0
- package/android/.gradle/8.0.2/fileHashes/fileHashes.bin +0 -0
- package/android/.gradle/8.0.2/fileHashes/fileHashes.lock +0 -0
- package/android/.gradle/8.0.2/fileHashes/resourceHashesCache.bin +0 -0
- package/android/.gradle/8.0.2/gc.properties +0 -0
- package/android/.gradle/buildOutputCleanup/buildOutputCleanup.lock +0 -0
- package/android/.gradle/buildOutputCleanup/cache.properties +2 -0
- package/android/.gradle/buildOutputCleanup/outputFiles.bin +0 -0
- package/android/.gradle/vcs-1/gc.properties +0 -0
- package/android/android.iml +40 -0
- package/android/build.gradle +59 -0
- package/android/gradle/wrapper/gradle-wrapper.jar +0 -0
- package/android/gradle/wrapper/gradle-wrapper.properties +6 -0
- package/android/gradle.properties +20 -0
- package/android/gradlew +244 -0
- package/android/gradlew.bat +92 -0
- package/android/local.properties +8 -0
- package/android/proguard-rules.pro +21 -0
- package/android/settings.gradle +2 -0
- package/android/src/androidTest/java/com/getcapacitor/android/ExampleInstrumentedTest.java +28 -0
- package/android/src/main/AndroidManifest.xml +12 -0
- package/android/src/main/java/ee/forgr/biometric/AuthActivity.java +129 -0
- package/android/src/main/java/ee/forgr/biometric/NativeBiometric.java +457 -0
- package/android/src/main/res/layout/activity_auth_acitivy.xml +12 -0
- package/android/src/main/res/layout/bridge_layout_main.xml +15 -0
- package/android/src/main/res/navigation/nav_graph.xml +28 -0
- package/android/src/main/res/values/colors.xml +3 -0
- package/android/src/main/res/values/dimens.xml +3 -0
- package/android/src/main/res/values/strings.xml +12 -0
- package/android/src/main/res/values/styles.xml +16 -0
- package/android/src/test/java/com/getcapacitor/ExampleUnitTest.java +18 -0
- package/dist/docs.json +426 -0
- package/dist/esm/definitions.d.ts +91 -0
- package/dist/esm/definitions.js +11 -0
- package/dist/esm/definitions.js.map +1 -0
- package/dist/esm/index.d.ts +4 -0
- package/dist/esm/index.js +7 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/web.d.ts +10 -0
- package/dist/esm/web.js +22 -0
- package/dist/esm/web.js.map +1 -0
- package/dist/plugin.cjs.js +47 -0
- package/dist/plugin.cjs.js.map +1 -0
- package/dist/plugin.js +50 -0
- package/dist/plugin.js.map +1 -0
- package/ios/Plugin/Info.plist +24 -0
- package/ios/Plugin/Plugin.h +10 -0
- package/ios/Plugin/Plugin.m +12 -0
- package/ios/Plugin/Plugin.swift +264 -0
- package/ios/Plugin.xcodeproj/project.pbxproj +554 -0
- package/ios/Plugin.xcodeproj/project.xcworkspace/contents.xcworkspacedata +7 -0
- package/ios/Plugin.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +8 -0
- package/ios/Plugin.xcodeproj/project.xcworkspace/xcuserdata/pilito.xcuserdatad/UserInterfaceState.xcuserstate +0 -0
- package/ios/Plugin.xcodeproj/xcuserdata/jmartinez.xcuserdatad/xcschemes/xcschememanagement.plist +14 -0
- package/ios/Plugin.xcodeproj/xcuserdata/josemartinez.xcuserdatad/xcschemes/xcschememanagement.plist +14 -0
- package/ios/Plugin.xcodeproj/xcuserdata/pilito.xcuserdatad/xcschemes/xcschememanagement.plist +14 -0
- package/ios/Plugin.xcworkspace/contents.xcworkspacedata +10 -0
- package/ios/Plugin.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +8 -0
- package/ios/Plugin.xcworkspace/xcuserdata/jmartinez.xcuserdatad/UserInterfaceState.xcuserstate +0 -0
- package/ios/Plugin.xcworkspace/xcuserdata/josemartinez.xcuserdatad/UserInterfaceState.xcuserstate +0 -0
- package/ios/Plugin.xcworkspace/xcuserdata/pilito.xcuserdatad/UserInterfaceState.xcuserstate +0 -0
- package/ios/PluginTests/Info.plist +22 -0
- package/ios/PluginTests/PluginTests.swift +35 -0
- package/ios/Podfile +16 -0
- package/ios/Podfile.lock +22 -0
- package/ios/Pods/Local Podspecs/Capacitor.podspec.json +34 -0
- package/ios/Pods/Local Podspecs/CapacitorCordova.podspec.json +26 -0
- package/ios/Pods/Manifest.lock +22 -0
- package/ios/Pods/Pods.xcodeproj/project.pbxproj +1626 -0
- package/ios/Pods/Pods.xcodeproj/xcuserdata/jmartinez.xcuserdatad/xcschemes/Capacitor.xcscheme +60 -0
- package/ios/Pods/Pods.xcodeproj/xcuserdata/jmartinez.xcuserdatad/xcschemes/CapacitorCordova.xcscheme +58 -0
- package/ios/Pods/Pods.xcodeproj/xcuserdata/jmartinez.xcuserdatad/xcschemes/Pods-Plugin.xcscheme +58 -0
- package/ios/Pods/Pods.xcodeproj/xcuserdata/jmartinez.xcuserdatad/xcschemes/Pods-PluginTests.xcscheme +58 -0
- package/ios/Pods/Pods.xcodeproj/xcuserdata/jmartinez.xcuserdatad/xcschemes/xcschememanagement.plist +39 -0
- package/ios/Pods/Pods.xcodeproj/xcuserdata/josemartinez.xcuserdatad/xcschemes/Capacitor.xcscheme +60 -0
- package/ios/Pods/Pods.xcodeproj/xcuserdata/josemartinez.xcuserdatad/xcschemes/CapacitorCordova.xcscheme +58 -0
- package/ios/Pods/Pods.xcodeproj/xcuserdata/josemartinez.xcuserdatad/xcschemes/Pods-Plugin.xcscheme +58 -0
- package/ios/Pods/Pods.xcodeproj/xcuserdata/josemartinez.xcuserdatad/xcschemes/Pods-PluginTests.xcscheme +58 -0
- package/ios/Pods/Pods.xcodeproj/xcuserdata/josemartinez.xcuserdatad/xcschemes/xcschememanagement.plist +39 -0
- package/ios/Pods/Pods.xcodeproj/xcuserdata/martindonadieu.xcuserdatad/xcschemes/Capacitor.xcscheme +58 -0
- package/ios/Pods/Pods.xcodeproj/xcuserdata/martindonadieu.xcuserdatad/xcschemes/CapacitorCordova.xcscheme +58 -0
- package/ios/Pods/Pods.xcodeproj/xcuserdata/martindonadieu.xcuserdatad/xcschemes/Pods-Plugin.xcscheme +58 -0
- package/ios/Pods/Pods.xcodeproj/xcuserdata/martindonadieu.xcuserdatad/xcschemes/Pods-PluginTests.xcscheme +58 -0
- package/ios/Pods/Pods.xcodeproj/xcuserdata/martindonadieu.xcuserdatad/xcschemes/xcschememanagement.plist +31 -0
- package/ios/Pods/Pods.xcodeproj/xcuserdata/pilito.xcuserdatad/xcschemes/xcschememanagement.plist +29 -0
- package/ios/Pods/Target Support Files/Capacitor/Capacitor-Info.plist +26 -0
- package/ios/Pods/Target Support Files/Capacitor/Capacitor-dummy.m +5 -0
- package/ios/Pods/Target Support Files/Capacitor/Capacitor-prefix.pch +12 -0
- package/ios/Pods/Target Support Files/Capacitor/Capacitor-umbrella.h +23 -0
- package/ios/Pods/Target Support Files/Capacitor/Capacitor.debug.xcconfig +16 -0
- package/ios/Pods/Target Support Files/Capacitor/Capacitor.modulemap +8 -0
- package/ios/Pods/Target Support Files/Capacitor/Capacitor.release.xcconfig +16 -0
- package/ios/Pods/Target Support Files/CapacitorCordova/CapacitorCordova-Info.plist +26 -0
- package/ios/Pods/Target Support Files/CapacitorCordova/CapacitorCordova-dummy.m +5 -0
- package/ios/Pods/Target Support Files/CapacitorCordova/CapacitorCordova-prefix.pch +12 -0
- package/ios/Pods/Target Support Files/CapacitorCordova/CapacitorCordova-umbrella.h +32 -0
- package/ios/Pods/Target Support Files/CapacitorCordova/CapacitorCordova.debug.xcconfig +13 -0
- package/ios/Pods/Target Support Files/CapacitorCordova/CapacitorCordova.modulemap +6 -0
- package/ios/Pods/Target Support Files/CapacitorCordova/CapacitorCordova.release.xcconfig +13 -0
- package/ios/Pods/Target Support Files/Pods-Plugin/Pods-Plugin-Info.plist +26 -0
- package/ios/Pods/Target Support Files/Pods-Plugin/Pods-Plugin-acknowledgements.markdown +53 -0
- package/ios/Pods/Target Support Files/Pods-Plugin/Pods-Plugin-acknowledgements.plist +91 -0
- package/ios/Pods/Target Support Files/Pods-Plugin/Pods-Plugin-dummy.m +5 -0
- package/ios/Pods/Target Support Files/Pods-Plugin/Pods-Plugin-umbrella.h +16 -0
- package/ios/Pods/Target Support Files/Pods-Plugin/Pods-Plugin.debug.xcconfig +14 -0
- package/ios/Pods/Target Support Files/Pods-Plugin/Pods-Plugin.modulemap +6 -0
- package/ios/Pods/Target Support Files/Pods-Plugin/Pods-Plugin.release.xcconfig +14 -0
- package/ios/Pods/Target Support Files/Pods-PluginTests/Pods-PluginTests-Info.plist +26 -0
- package/ios/Pods/Target Support Files/Pods-PluginTests/Pods-PluginTests-acknowledgements.markdown +53 -0
- package/ios/Pods/Target Support Files/Pods-PluginTests/Pods-PluginTests-acknowledgements.plist +91 -0
- package/ios/Pods/Target Support Files/Pods-PluginTests/Pods-PluginTests-dummy.m +5 -0
- package/ios/Pods/Target Support Files/Pods-PluginTests/Pods-PluginTests-frameworks.sh +188 -0
- package/ios/Pods/Target Support Files/Pods-PluginTests/Pods-PluginTests-umbrella.h +16 -0
- package/ios/Pods/Target Support Files/Pods-PluginTests/Pods-PluginTests.debug.xcconfig +15 -0
- package/ios/Pods/Target Support Files/Pods-PluginTests/Pods-PluginTests.modulemap +6 -0
- package/ios/Pods/Target Support Files/Pods-PluginTests/Pods-PluginTests.release.xcconfig +15 -0
- package/package.json +80 -0
- package/readme.md +284 -0
package/dist/plugin.js
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
var capacitorApp = (function (exports, core) {
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
exports.BiometryType = void 0;
|
|
5
|
+
(function (BiometryType) {
|
|
6
|
+
BiometryType[BiometryType["NONE"] = 0] = "NONE";
|
|
7
|
+
BiometryType[BiometryType["TOUCH_ID"] = 1] = "TOUCH_ID";
|
|
8
|
+
BiometryType[BiometryType["FACE_ID"] = 2] = "FACE_ID";
|
|
9
|
+
BiometryType[BiometryType["FINGERPRINT"] = 3] = "FINGERPRINT";
|
|
10
|
+
BiometryType[BiometryType["FACE_AUTHENTICATION"] = 4] = "FACE_AUTHENTICATION";
|
|
11
|
+
BiometryType[BiometryType["IRIS_AUTHENTICATION"] = 5] = "IRIS_AUTHENTICATION";
|
|
12
|
+
BiometryType[BiometryType["MULTIPLE"] = 6] = "MULTIPLE";
|
|
13
|
+
})(exports.BiometryType || (exports.BiometryType = {}));
|
|
14
|
+
|
|
15
|
+
const NativeBiometric = core.registerPlugin("NativeBiometric", {
|
|
16
|
+
web: () => Promise.resolve().then(function () { return web; }).then((m) => new m.NativeBiometricWeb()),
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
class NativeBiometricWeb extends core.WebPlugin {
|
|
20
|
+
constructor() {
|
|
21
|
+
super();
|
|
22
|
+
}
|
|
23
|
+
isAvailable() {
|
|
24
|
+
throw new Error("Method not implemented.");
|
|
25
|
+
}
|
|
26
|
+
verifyIdentity(_options) {
|
|
27
|
+
throw new Error("Method not implemented.");
|
|
28
|
+
}
|
|
29
|
+
getCredentials(_options) {
|
|
30
|
+
throw new Error("Method not implemented.");
|
|
31
|
+
}
|
|
32
|
+
setCredentials(_options) {
|
|
33
|
+
throw new Error("Method not implemented.");
|
|
34
|
+
}
|
|
35
|
+
deleteCredentials(_options) {
|
|
36
|
+
throw new Error("Method not implemented.");
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
var web = /*#__PURE__*/Object.freeze({
|
|
41
|
+
__proto__: null,
|
|
42
|
+
NativeBiometricWeb: NativeBiometricWeb
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
exports.NativeBiometric = NativeBiometric;
|
|
46
|
+
|
|
47
|
+
return exports;
|
|
48
|
+
|
|
49
|
+
})({}, capacitorExports);
|
|
50
|
+
//# sourceMappingURL=plugin.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plugin.js","sources":["esm/definitions.js","esm/index.js","esm/web.js"],"sourcesContent":["export var BiometryType;\n(function (BiometryType) {\n BiometryType[BiometryType[\"NONE\"] = 0] = \"NONE\";\n BiometryType[BiometryType[\"TOUCH_ID\"] = 1] = \"TOUCH_ID\";\n BiometryType[BiometryType[\"FACE_ID\"] = 2] = \"FACE_ID\";\n BiometryType[BiometryType[\"FINGERPRINT\"] = 3] = \"FINGERPRINT\";\n BiometryType[BiometryType[\"FACE_AUTHENTICATION\"] = 4] = \"FACE_AUTHENTICATION\";\n BiometryType[BiometryType[\"IRIS_AUTHENTICATION\"] = 5] = \"IRIS_AUTHENTICATION\";\n BiometryType[BiometryType[\"MULTIPLE\"] = 6] = \"MULTIPLE\";\n})(BiometryType || (BiometryType = {}));\n//# sourceMappingURL=definitions.js.map","import { registerPlugin } from \"@capacitor/core\";\nconst NativeBiometric = registerPlugin(\"NativeBiometric\", {\n web: () => import(\"./web\").then((m) => new m.NativeBiometricWeb()),\n});\nexport * from \"./definitions\";\nexport { NativeBiometric };\n//# sourceMappingURL=index.js.map","import { WebPlugin } from \"@capacitor/core\";\nexport class NativeBiometricWeb extends WebPlugin {\n constructor() {\n super();\n }\n isAvailable() {\n throw new Error(\"Method not implemented.\");\n }\n verifyIdentity(_options) {\n throw new Error(\"Method not implemented.\");\n }\n getCredentials(_options) {\n throw new Error(\"Method not implemented.\");\n }\n setCredentials(_options) {\n throw new Error(\"Method not implemented.\");\n }\n deleteCredentials(_options) {\n throw new Error(\"Method not implemented.\");\n }\n}\n//# sourceMappingURL=web.js.map"],"names":["BiometryType","registerPlugin","WebPlugin"],"mappings":";;;AAAWA,kCAAa;IACxB,CAAC,UAAU,YAAY,EAAE;IACzB,IAAI,YAAY,CAAC,YAAY,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,GAAG,MAAM,CAAC;IACpD,IAAI,YAAY,CAAC,YAAY,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,GAAG,UAAU,CAAC;IAC5D,IAAI,YAAY,CAAC,YAAY,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,GAAG,SAAS,CAAC;IAC1D,IAAI,YAAY,CAAC,YAAY,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,GAAG,aAAa,CAAC;IAClE,IAAI,YAAY,CAAC,YAAY,CAAC,qBAAqB,CAAC,GAAG,CAAC,CAAC,GAAG,qBAAqB,CAAC;IAClF,IAAI,YAAY,CAAC,YAAY,CAAC,qBAAqB,CAAC,GAAG,CAAC,CAAC,GAAG,qBAAqB,CAAC;IAClF,IAAI,YAAY,CAAC,YAAY,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,GAAG,UAAU,CAAC;IAC5D,CAAC,EAAEA,oBAAY,KAAKA,oBAAY,GAAG,EAAE,CAAC,CAAC;;ACRlC,UAAC,eAAe,GAAGC,mBAAc,CAAC,iBAAiB,EAAE;IAC1D,IAAI,GAAG,EAAE,MAAM,mDAAe,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,kBAAkB,EAAE,CAAC;IACtE,CAAC;;ICFM,MAAM,kBAAkB,SAASC,cAAS,CAAC;IAClD,IAAI,WAAW,GAAG;IAClB,QAAQ,KAAK,EAAE,CAAC;IAChB,KAAK;IACL,IAAI,WAAW,GAAG;IAClB,QAAQ,MAAM,IAAI,KAAK,CAAC,yBAAyB,CAAC,CAAC;IACnD,KAAK;IACL,IAAI,cAAc,CAAC,QAAQ,EAAE;IAC7B,QAAQ,MAAM,IAAI,KAAK,CAAC,yBAAyB,CAAC,CAAC;IACnD,KAAK;IACL,IAAI,cAAc,CAAC,QAAQ,EAAE;IAC7B,QAAQ,MAAM,IAAI,KAAK,CAAC,yBAAyB,CAAC,CAAC;IACnD,KAAK;IACL,IAAI,cAAc,CAAC,QAAQ,EAAE;IAC7B,QAAQ,MAAM,IAAI,KAAK,CAAC,yBAAyB,CAAC,CAAC;IACnD,KAAK;IACL,IAAI,iBAAiB,CAAC,QAAQ,EAAE;IAChC,QAAQ,MAAM,IAAI,KAAK,CAAC,yBAAyB,CAAC,CAAC;IACnD,KAAK;IACL;;;;;;;;;;;;;;;"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
+
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
3
|
+
<plist version="1.0">
|
|
4
|
+
<dict>
|
|
5
|
+
<key>CFBundleDevelopmentRegion</key>
|
|
6
|
+
<string>$(DEVELOPMENT_LANGUAGE)</string>
|
|
7
|
+
<key>CFBundleExecutable</key>
|
|
8
|
+
<string>$(EXECUTABLE_NAME)</string>
|
|
9
|
+
<key>CFBundleIdentifier</key>
|
|
10
|
+
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
|
|
11
|
+
<key>CFBundleInfoDictionaryVersion</key>
|
|
12
|
+
<string>6.0</string>
|
|
13
|
+
<key>CFBundleName</key>
|
|
14
|
+
<string>$(PRODUCT_NAME)</string>
|
|
15
|
+
<key>CFBundlePackageType</key>
|
|
16
|
+
<string>FMWK</string>
|
|
17
|
+
<key>CFBundleShortVersionString</key>
|
|
18
|
+
<string>1.0</string>
|
|
19
|
+
<key>CFBundleVersion</key>
|
|
20
|
+
<string>$(CURRENT_PROJECT_VERSION)</string>
|
|
21
|
+
<key>NSPrincipalClass</key>
|
|
22
|
+
<string></string>
|
|
23
|
+
</dict>
|
|
24
|
+
</plist>
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
#import <UIKit/UIKit.h>
|
|
2
|
+
|
|
3
|
+
//! Project version number for Plugin.
|
|
4
|
+
FOUNDATION_EXPORT double PluginVersionNumber;
|
|
5
|
+
|
|
6
|
+
//! Project version string for Plugin.
|
|
7
|
+
FOUNDATION_EXPORT const unsigned char PluginVersionString[];
|
|
8
|
+
|
|
9
|
+
// In this header, you should import all the public headers of your framework using statements like #import <Plugin/PublicHeader.h>
|
|
10
|
+
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
#import <Foundation/Foundation.h>
|
|
2
|
+
#import <Capacitor/Capacitor.h>
|
|
3
|
+
|
|
4
|
+
// Define the plugin using the CAP_PLUGIN Macro, and
|
|
5
|
+
// each method the plugin supports using the CAP_PLUGIN_METHOD macro.
|
|
6
|
+
CAP_PLUGIN(NativeBiometric, "NativeBiometric",
|
|
7
|
+
CAP_PLUGIN_METHOD(isAvailable, CAPPluginReturnPromise);
|
|
8
|
+
CAP_PLUGIN_METHOD(verifyIdentity, CAPPluginReturnPromise);
|
|
9
|
+
CAP_PLUGIN_METHOD(getCredentials, CAPPluginReturnPromise);
|
|
10
|
+
CAP_PLUGIN_METHOD(setCredentials, CAPPluginReturnPromise);
|
|
11
|
+
CAP_PLUGIN_METHOD(deleteCredentials, CAPPluginReturnPromise);
|
|
12
|
+
)
|
|
@@ -0,0 +1,264 @@
|
|
|
1
|
+
import Foundation
|
|
2
|
+
import Capacitor
|
|
3
|
+
import LocalAuthentication
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Please read the Capacitor iOS Plugin Development Guide
|
|
7
|
+
* here: https://capacitor.ionicframework.com/docs/plugins/ios
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
@objc(NativeBiometric)
|
|
11
|
+
public class NativeBiometric: CAPPlugin {
|
|
12
|
+
|
|
13
|
+
struct Credentials {
|
|
14
|
+
var username: String
|
|
15
|
+
var password: String
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
enum KeychainError: Error {
|
|
19
|
+
case noPassword
|
|
20
|
+
case unexpectedPasswordData
|
|
21
|
+
case duplicateItem
|
|
22
|
+
case unhandledError(status: OSStatus)
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
typealias JSObject = [String: Any]
|
|
26
|
+
|
|
27
|
+
@objc func isAvailable(_ call: CAPPluginCall) {
|
|
28
|
+
let context = LAContext()
|
|
29
|
+
var error: NSError?
|
|
30
|
+
var obj = JSObject()
|
|
31
|
+
|
|
32
|
+
obj["isAvailable"] = false
|
|
33
|
+
obj["biometryType"] = 0
|
|
34
|
+
|
|
35
|
+
let useFallback = call.getBool("useFallback", false)
|
|
36
|
+
let policy = useFallback ? LAPolicy.deviceOwnerAuthentication : LAPolicy.deviceOwnerAuthenticationWithBiometrics
|
|
37
|
+
|
|
38
|
+
if context.canEvaluatePolicy(policy, error: &error) {
|
|
39
|
+
switch context.biometryType {
|
|
40
|
+
case .touchID:
|
|
41
|
+
obj["biometryType"] = 1
|
|
42
|
+
case .faceID:
|
|
43
|
+
obj["biometryType"] = 2
|
|
44
|
+
default:
|
|
45
|
+
obj["biomertryType"] = 0
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
obj["isAvailable"] = true
|
|
49
|
+
call.resolve(obj)
|
|
50
|
+
} else {
|
|
51
|
+
guard let authError = error else {
|
|
52
|
+
obj["errorCode"] = 0
|
|
53
|
+
call.resolve(obj)
|
|
54
|
+
return
|
|
55
|
+
}
|
|
56
|
+
var errorCode = 0
|
|
57
|
+
switch authError.code {
|
|
58
|
+
case LAError.biometryNotAvailable.rawValue:
|
|
59
|
+
errorCode = 1
|
|
60
|
+
|
|
61
|
+
case LAError.biometryLockout.rawValue:
|
|
62
|
+
errorCode = 2 // "Authentication could not continue because the user has been locked out of biometric authentication, due to failing authentication too many times."
|
|
63
|
+
|
|
64
|
+
case LAError.biometryNotEnrolled.rawValue:
|
|
65
|
+
errorCode = 3// message = "Authentication could not start because the user has not enrolled in biometric authentication."
|
|
66
|
+
|
|
67
|
+
default:
|
|
68
|
+
errorCode = 0 // "Did not find error code on LAError object"
|
|
69
|
+
}
|
|
70
|
+
obj["errorCode"] = errorCode
|
|
71
|
+
call.resolve(obj)
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
@objc func verifyIdentity(_ call: CAPPluginCall) {
|
|
77
|
+
let context = LAContext()
|
|
78
|
+
var canEvaluateError: NSError?
|
|
79
|
+
|
|
80
|
+
let useFallback = call.getBool("useFallback", false)
|
|
81
|
+
context.localizedFallbackTitle = useFallback ? nil : ""
|
|
82
|
+
|
|
83
|
+
let policy = useFallback ? LAPolicy.deviceOwnerAuthentication : LAPolicy.deviceOwnerAuthenticationWithBiometrics
|
|
84
|
+
|
|
85
|
+
if context.canEvaluatePolicy(policy, error: &canEvaluateError) {
|
|
86
|
+
|
|
87
|
+
let reason = call.getString("reason") ?? "For biometric authentication"
|
|
88
|
+
|
|
89
|
+
context.evaluatePolicy(policy, localizedReason: reason) { (success, evaluateError) in
|
|
90
|
+
|
|
91
|
+
if success {
|
|
92
|
+
call.resolve()
|
|
93
|
+
} else {
|
|
94
|
+
var errorCode = "0"
|
|
95
|
+
guard let error = evaluateError
|
|
96
|
+
else {
|
|
97
|
+
call.reject("Biometrics Error", "0")
|
|
98
|
+
return
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
switch error._code {
|
|
102
|
+
|
|
103
|
+
case LAError.authenticationFailed.rawValue:
|
|
104
|
+
errorCode = "10"
|
|
105
|
+
|
|
106
|
+
case LAError.appCancel.rawValue:
|
|
107
|
+
errorCode = "11"
|
|
108
|
+
|
|
109
|
+
case LAError.invalidContext.rawValue:
|
|
110
|
+
errorCode = "12"
|
|
111
|
+
|
|
112
|
+
case LAError.notInteractive.rawValue:
|
|
113
|
+
errorCode = "13"
|
|
114
|
+
|
|
115
|
+
case LAError.passcodeNotSet.rawValue:
|
|
116
|
+
errorCode = "14"
|
|
117
|
+
|
|
118
|
+
case LAError.systemCancel.rawValue:
|
|
119
|
+
errorCode = "15"
|
|
120
|
+
|
|
121
|
+
case LAError.userCancel.rawValue:
|
|
122
|
+
errorCode = "16"
|
|
123
|
+
|
|
124
|
+
case LAError.userFallback.rawValue:
|
|
125
|
+
errorCode = "17"
|
|
126
|
+
|
|
127
|
+
case LAError.biometryNotAvailable.rawValue:
|
|
128
|
+
errorCode = "1"
|
|
129
|
+
|
|
130
|
+
case LAError.biometryLockout.rawValue:
|
|
131
|
+
errorCode = "2" // "Authentication could not continue because the user has been locked out of biometric authentication, due to failing authentication too many times."
|
|
132
|
+
|
|
133
|
+
case LAError.biometryNotEnrolled.rawValue:
|
|
134
|
+
errorCode = "3" // message = "Authentication could not start because the user has not enrolled in biometric authentication."
|
|
135
|
+
|
|
136
|
+
default:
|
|
137
|
+
errorCode = "0" // Biometrics unavailable
|
|
138
|
+
}
|
|
139
|
+
call.reject(error.localizedDescription, errorCode, error )
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
} else {
|
|
145
|
+
call.reject("Authentication not available")
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
@objc func getCredentials(_ call: CAPPluginCall) {
|
|
150
|
+
guard let server = call.getString("server") else {
|
|
151
|
+
call.reject("No server name was provided")
|
|
152
|
+
return
|
|
153
|
+
}
|
|
154
|
+
do {
|
|
155
|
+
let credentials = try getCredentialsFromKeychain(server)
|
|
156
|
+
var obj = JSObject()
|
|
157
|
+
obj["username"] = credentials.username
|
|
158
|
+
obj["password"] = credentials.password
|
|
159
|
+
call.resolve(obj)
|
|
160
|
+
} catch {
|
|
161
|
+
call.reject(error.localizedDescription)
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
@objc func setCredentials(_ call: CAPPluginCall) {
|
|
166
|
+
|
|
167
|
+
guard let server = call.getString("server"), let username = call.getString("username"), let password = call.getString("password") else {
|
|
168
|
+
call.reject("Missing properties")
|
|
169
|
+
return
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
let credentials = Credentials(username: username, password: password)
|
|
173
|
+
|
|
174
|
+
do {
|
|
175
|
+
try storeCredentialsInKeychain(credentials, server)
|
|
176
|
+
call.resolve()
|
|
177
|
+
} catch KeychainError.duplicateItem {
|
|
178
|
+
do {
|
|
179
|
+
try updateCredentialsInKeychain(credentials, server)
|
|
180
|
+
call.resolve()
|
|
181
|
+
} catch {
|
|
182
|
+
call.reject(error.localizedDescription)
|
|
183
|
+
}
|
|
184
|
+
} catch {
|
|
185
|
+
call.reject(error.localizedDescription)
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
@objc func deleteCredentials(_ call: CAPPluginCall) {
|
|
190
|
+
guard let server = call.getString("server") else {
|
|
191
|
+
call.reject("No server name was provided")
|
|
192
|
+
return
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
do {
|
|
196
|
+
try deleteCredentialsFromKeychain(server)
|
|
197
|
+
call.resolve()
|
|
198
|
+
} catch {
|
|
199
|
+
call.reject(error.localizedDescription)
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
// Store user Credentials in Keychain
|
|
204
|
+
func storeCredentialsInKeychain(_ credentials: Credentials, _ server: String) throws {
|
|
205
|
+
let query: [String: Any] = [kSecClass as String: kSecClassInternetPassword,
|
|
206
|
+
kSecAttrAccount as String: credentials.username,
|
|
207
|
+
kSecAttrServer as String: server,
|
|
208
|
+
kSecValueData as String: credentials.password.data(using: .utf8)!]
|
|
209
|
+
|
|
210
|
+
let status = SecItemAdd(query as CFDictionary, nil)
|
|
211
|
+
|
|
212
|
+
guard status != errSecDuplicateItem else { throw KeychainError.duplicateItem }
|
|
213
|
+
guard status == errSecSuccess else { throw KeychainError.unhandledError(status: status) }
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
// Update user Credentials in Keychain
|
|
217
|
+
func updateCredentialsInKeychain(_ credentials: Credentials, _ server: String) throws {
|
|
218
|
+
let query: [String: Any] = [kSecClass as String: kSecClassInternetPassword,
|
|
219
|
+
kSecAttrServer as String: server]
|
|
220
|
+
|
|
221
|
+
let account = credentials.username
|
|
222
|
+
let password = credentials.password.data(using: String.Encoding.utf8)!
|
|
223
|
+
let attributes: [String: Any] = [kSecAttrAccount as String: account,
|
|
224
|
+
kSecValueData as String: password]
|
|
225
|
+
|
|
226
|
+
let status = SecItemUpdate(query as CFDictionary, attributes as CFDictionary)
|
|
227
|
+
guard status != errSecItemNotFound else { throw KeychainError.noPassword }
|
|
228
|
+
guard status == errSecSuccess else { throw KeychainError.unhandledError(status: status) }
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
// Get user Credentials from Keychain
|
|
232
|
+
func getCredentialsFromKeychain(_ server: String) throws -> Credentials {
|
|
233
|
+
let query: [String: Any] = [kSecClass as String: kSecClassInternetPassword,
|
|
234
|
+
kSecAttrServer as String: server,
|
|
235
|
+
kSecMatchLimit as String: kSecMatchLimitOne,
|
|
236
|
+
kSecReturnAttributes as String: true,
|
|
237
|
+
kSecReturnData as String: true]
|
|
238
|
+
|
|
239
|
+
var item: CFTypeRef?
|
|
240
|
+
let status = SecItemCopyMatching(query as CFDictionary, &item)
|
|
241
|
+
guard status != errSecItemNotFound else { throw KeychainError.noPassword }
|
|
242
|
+
guard status == errSecSuccess else { throw KeychainError.unhandledError(status: status) }
|
|
243
|
+
|
|
244
|
+
guard let existingItem = item as? [String: Any],
|
|
245
|
+
let passwordData = existingItem[kSecValueData as String] as? Data,
|
|
246
|
+
let password = String(data: passwordData, encoding: .utf8),
|
|
247
|
+
let username = existingItem[kSecAttrAccount as String] as? String
|
|
248
|
+
else {
|
|
249
|
+
throw KeychainError.unexpectedPasswordData
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
let credentials = Credentials(username: username, password: password)
|
|
253
|
+
return credentials
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
// Delete user Credentials from Keychain
|
|
257
|
+
func deleteCredentialsFromKeychain(_ server: String)throws {
|
|
258
|
+
let query: [String: Any] = [kSecClass as String: kSecClassInternetPassword,
|
|
259
|
+
kSecAttrServer as String: server]
|
|
260
|
+
|
|
261
|
+
let status = SecItemDelete(query as CFDictionary)
|
|
262
|
+
guard status == errSecSuccess || status == errSecItemNotFound else { throw KeychainError.unhandledError(status: status) }
|
|
263
|
+
}
|
|
264
|
+
}
|