expo-local-authentication 13.7.0 → 14.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/CHANGELOG.md CHANGED
@@ -10,6 +10,29 @@
10
10
 
11
11
  ### 💡 Others
12
12
 
13
+ ## 14.0.0 — 2024-04-18
14
+
15
+ ### 🛠 Breaking changes
16
+
17
+ - `SecurityLevel.BIOMETRIC` has been deprecated in favour of `SecurityLevel.BIOMETRIC_STRONG` and `SecurityLevel.BIOMETRIC_WEAK`. Using `SecurityLevel.BIOMETRIC` might lead to unexpected behaviour. ([#26768](https://github.com/expo/expo/pull/26768) by [@behenate](https://github.com/behenate))
18
+
19
+ ### 🎉 New features
20
+
21
+ - [Android] Add support for `weak` and `strong` biometric authentication. ([#26768](https://github.com/expo/expo/pull/26768) by [@behenate](https://github.com/behenate))
22
+
23
+ ### 💡 Others
24
+
25
+ - Prevent config plugin from writing permissions until prebuild. ([#28107](https://github.com/expo/expo/pull/28107) by [@EvanBacon](https://github.com/EvanBacon))
26
+ - drop unused web `name` property. ([#27437](https://github.com/expo/expo/pull/27437) by [@EvanBacon](https://github.com/EvanBacon))
27
+ - Removed deprecated backward compatible Gradle settings. ([#28083](https://github.com/expo/expo/pull/28083) by [@kudo](https://github.com/kudo))
28
+
29
+ ## 13.8.0 — 2023-11-14
30
+
31
+ ### 🛠 Breaking changes
32
+
33
+ - Bumped iOS deployment target to 13.4. ([#25063](https://github.com/expo/expo/pull/25063) by [@gabrieldonadel](https://github.com/gabrieldonadel))
34
+ - On `Android` bump `compileSdkVersion` and `targetSdkVersion` to `34`. ([#24708](https://github.com/expo/expo/pull/24708) by [@alanjhughes](https://github.com/alanjhughes))
35
+
13
36
  ## 13.7.0 — 2023-10-17
14
37
 
15
38
  ### 🛠 Breaking changes
@@ -1,109 +1,23 @@
1
1
  apply plugin: 'com.android.library'
2
- apply plugin: 'kotlin-android'
3
- apply plugin: 'maven-publish'
4
2
 
5
3
  group = 'host.exp.exponent'
6
- version = '13.7.0'
4
+ version = '14.0.0'
7
5
 
8
6
  def expoModulesCorePlugin = new File(project(":expo-modules-core").projectDir.absolutePath, "ExpoModulesCorePlugin.gradle")
9
- if (expoModulesCorePlugin.exists()) {
10
- apply from: expoModulesCorePlugin
11
- applyKotlinExpoModulesCorePlugin()
12
- // Remove this check, but keep the contents after SDK49 support is dropped
13
- if (safeExtGet("expoProvidesDefaultConfig", false)) {
14
- useExpoPublishing()
15
- useCoreDependencies()
16
- }
17
- }
18
-
19
- buildscript {
20
- // Simple helper that allows the root project to override versions declared by this library.
21
- ext.safeExtGet = { prop, fallback ->
22
- rootProject.ext.has(prop) ? rootProject.ext.get(prop) : fallback
23
- }
24
-
25
- // Ensures backward compatibility
26
- ext.getKotlinVersion = {
27
- if (ext.has("kotlinVersion")) {
28
- ext.kotlinVersion()
29
- } else {
30
- ext.safeExtGet("kotlinVersion", "1.8.10")
31
- }
32
- }
33
-
34
- repositories {
35
- mavenCentral()
36
- }
37
-
38
- dependencies {
39
- classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:${getKotlinVersion()}")
40
- }
41
- }
42
-
43
- // Remove this if and it's contents, when support for SDK49 is dropped
44
- if (!safeExtGet("expoProvidesDefaultConfig", false)) {
45
- afterEvaluate {
46
- publishing {
47
- publications {
48
- release(MavenPublication) {
49
- from components.release
50
- }
51
- }
52
- repositories {
53
- maven {
54
- url = mavenLocal().url
55
- }
56
- }
57
- }
58
- }
59
- }
7
+ apply from: expoModulesCorePlugin
8
+ applyKotlinExpoModulesCorePlugin()
9
+ useCoreDependencies()
10
+ useDefaultAndroidSdkVersions()
11
+ useExpoPublishing()
60
12
 
61
13
  android {
62
- // Remove this if and it's contents, when support for SDK49 is dropped
63
- if (!safeExtGet("expoProvidesDefaultConfig", false)) {
64
- compileSdkVersion safeExtGet("compileSdkVersion", 33)
65
-
66
- defaultConfig {
67
- minSdkVersion safeExtGet("minSdkVersion", 23)
68
- targetSdkVersion safeExtGet("targetSdkVersion", 33)
69
- }
70
-
71
- publishing {
72
- singleVariant("release") {
73
- withSourcesJar()
74
- }
75
- }
76
-
77
- lintOptions {
78
- abortOnError false
79
- }
80
- }
81
-
82
- def agpVersion = com.android.Version.ANDROID_GRADLE_PLUGIN_VERSION
83
- if (agpVersion.tokenize('.')[0].toInteger() < 8) {
84
- compileOptions {
85
- sourceCompatibility JavaVersion.VERSION_11
86
- targetCompatibility JavaVersion.VERSION_11
87
- }
88
-
89
- kotlinOptions {
90
- jvmTarget = JavaVersion.VERSION_11.majorVersion
91
- }
92
- }
93
-
94
14
  namespace "expo.modules.localauthentication"
95
15
  defaultConfig {
96
16
  versionCode 30
97
- versionName "13.7.0"
17
+ versionName "14.0.0"
98
18
  }
99
19
  }
100
20
 
101
21
  dependencies {
102
- // Remove this if and it's contents, when support for SDK49 is dropped
103
- if (!safeExtGet("expoProvidesDefaultConfig", false)) {
104
- implementation project(':expo-modules-core')
105
- implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:${getKotlinVersion()}"
106
- }
107
-
108
22
  implementation "androidx.biometric:biometric:1.2.0-alpha04"
109
23
  }
@@ -17,8 +17,6 @@ import expo.modules.kotlin.exception.UnexpectedException
17
17
  import expo.modules.kotlin.functions.Queues
18
18
  import expo.modules.kotlin.modules.Module
19
19
  import expo.modules.kotlin.modules.ModuleDefinition
20
- import expo.modules.kotlin.records.Field
21
- import expo.modules.kotlin.records.Record
22
20
  import kotlinx.coroutines.launch
23
21
  import java.util.concurrent.Executor
24
22
  import java.util.concurrent.Executors
@@ -28,28 +26,15 @@ private const val AUTHENTICATION_TYPE_FACIAL_RECOGNITION = 2
28
26
  private const val AUTHENTICATION_TYPE_IRIS = 3
29
27
  private const val SECURITY_LEVEL_NONE = 0
30
28
  private const val SECURITY_LEVEL_SECRET = 1
31
- private const val SECURITY_LEVEL_BIOMETRIC = 2
29
+ private const val SECURITY_LEVEL_BIOMETRIC_WEAK = 2
30
+ private const val SECURITY_LEVEL_BIOMETRIC_STRONG = 3
32
31
  private const val DEVICE_CREDENTIAL_FALLBACK_CODE = 6
33
32
 
34
- class AuthOptions : Record {
35
- @Field
36
- val promptMessage: String = ""
37
-
38
- @Field
39
- val cancelLabel: String = ""
40
-
41
- @Field
42
- val disableDeviceFallback: Boolean = false
43
-
44
- @Field
45
- val requireConfirmation: Boolean = true
46
- }
47
-
48
33
  class LocalAuthenticationModule : Module() {
49
34
  override fun definition() = ModuleDefinition {
50
35
  Name("ExpoLocalAuthentication")
51
36
 
52
- AsyncFunction("supportedAuthenticationTypesAsync") {
37
+ AsyncFunction<Set<Int>>("supportedAuthenticationTypesAsync") {
53
38
  val results = mutableSetOf<Int>()
54
39
  if (canAuthenticateUsingWeakBiometrics() == BiometricManager.BIOMETRIC_ERROR_NO_HARDWARE) {
55
40
  return@AsyncFunction results
@@ -67,21 +52,24 @@ class LocalAuthenticationModule : Module() {
67
52
  return@AsyncFunction results
68
53
  }
69
54
 
70
- AsyncFunction("hasHardwareAsync") {
55
+ AsyncFunction<Boolean>("hasHardwareAsync") {
71
56
  canAuthenticateUsingWeakBiometrics() != BiometricManager.BIOMETRIC_ERROR_NO_HARDWARE
72
57
  }
73
58
 
74
- AsyncFunction("isEnrolledAsync") {
59
+ AsyncFunction<Boolean>("isEnrolledAsync") {
75
60
  canAuthenticateUsingWeakBiometrics() == BiometricManager.BIOMETRIC_SUCCESS
76
61
  }
77
62
 
78
- AsyncFunction("getEnrolledLevelAsync") {
63
+ AsyncFunction<Int>("getEnrolledLevelAsync") {
79
64
  var level = SECURITY_LEVEL_NONE
80
65
  if (isDeviceSecure) {
81
66
  level = SECURITY_LEVEL_SECRET
82
67
  }
83
68
  if (canAuthenticateUsingWeakBiometrics() == BiometricManager.BIOMETRIC_SUCCESS) {
84
- level = SECURITY_LEVEL_BIOMETRIC
69
+ level = SECURITY_LEVEL_BIOMETRIC_WEAK
70
+ }
71
+ if (canAuthenticateUsingStrongBiometrics() == BiometricManager.BIOMETRIC_SUCCESS) {
72
+ level = SECURITY_LEVEL_BIOMETRIC_STRONG
85
73
  }
86
74
  return@AsyncFunction level
87
75
  }
@@ -222,8 +210,12 @@ class LocalAuthenticationModule : Module() {
222
210
 
223
211
  val promptMessage = options.promptMessage
224
212
  val cancelLabel = options.cancelLabel
225
- val disableDeviceFallback = options.disableDeviceFallback
226
213
  val requireConfirmation = options.requireConfirmation
214
+ val allowedAuthenticators = if (options.disableDeviceFallback) {
215
+ options.biometricsSecurityLevel.toNativeBiometricSecurityLevel()
216
+ } else {
217
+ options.biometricsSecurityLevel.toNativeBiometricSecurityLevel() or BiometricManager.Authenticators.DEVICE_CREDENTIAL
218
+ }
227
219
 
228
220
  isAuthenticating = true
229
221
  this.promise = promise
@@ -231,14 +223,9 @@ class LocalAuthenticationModule : Module() {
231
223
  biometricPrompt = BiometricPrompt(fragmentActivity, executor, authenticationCallback)
232
224
  val promptInfoBuilder = PromptInfo.Builder().apply {
233
225
  setTitle(promptMessage)
234
-
235
- if (disableDeviceFallback) {
226
+ setAllowedAuthenticators(allowedAuthenticators)
227
+ if (options.disableDeviceFallback) {
236
228
  setNegativeButtonText(cancelLabel)
237
- } else {
238
- setAllowedAuthenticators(
239
- BiometricManager.Authenticators.BIOMETRIC_WEAK
240
- or BiometricManager.Authenticators.DEVICE_CREDENTIAL
241
- )
242
229
  }
243
230
  setConfirmationRequired(requireConfirmation)
244
231
  }
@@ -336,6 +323,9 @@ class LocalAuthenticationModule : Module() {
336
323
  private fun canAuthenticateUsingWeakBiometrics(): Int =
337
324
  biometricManager.canAuthenticate(BiometricManager.Authenticators.BIOMETRIC_WEAK)
338
325
 
326
+ private fun canAuthenticateUsingStrongBiometrics(): Int =
327
+ biometricManager.canAuthenticate(BiometricManager.Authenticators.BIOMETRIC_STRONG)
328
+
339
329
  private fun createResponse(
340
330
  error: String? = null,
341
331
  warning: String? = null
@@ -0,0 +1,35 @@
1
+ package expo.modules.localauthentication
2
+
3
+ import androidx.biometric.BiometricManager
4
+ import expo.modules.kotlin.records.Field
5
+ import expo.modules.kotlin.records.Record
6
+ import expo.modules.kotlin.types.Enumerable
7
+
8
+ internal enum class BiometricsSecurityLevel(val value: String) : Enumerable {
9
+ WEAK("weak"),
10
+ STRONG("strong");
11
+
12
+ fun toNativeBiometricSecurityLevel(): Int {
13
+ return when (this) {
14
+ WEAK -> BiometricManager.Authenticators.BIOMETRIC_WEAK
15
+ STRONG -> BiometricManager.Authenticators.BIOMETRIC_STRONG
16
+ }
17
+ }
18
+ }
19
+
20
+ internal class AuthOptions : Record {
21
+ @Field
22
+ val promptMessage: String = ""
23
+
24
+ @Field
25
+ val cancelLabel: String = ""
26
+
27
+ @Field
28
+ val disableDeviceFallback: Boolean = false
29
+
30
+ @Field
31
+ val requireConfirmation: Boolean = true
32
+
33
+ @Field
34
+ val biometricsSecurityLevel: BiometricsSecurityLevel = BiometricsSecurityLevel.WEAK
35
+ }
@@ -1,6 +1,5 @@
1
1
  import { AuthenticationType, SecurityLevel } from './LocalAuthentication.types';
2
2
  declare const _default: {
3
- readonly name: string;
4
3
  hasHardwareAsync(): Promise<boolean>;
5
4
  isEnrolledAsync(): Promise<boolean>;
6
5
  getEnrolledLevelAsync(): Promise<SecurityLevel>;
@@ -1 +1 @@
1
- {"version":3,"file":"ExpoLocalAuthentication.web.d.ts","sourceRoot":"","sources":["../src/ExpoLocalAuthentication.web.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;;;wBAMpD,QAAQ,OAAO,CAAC;uBAGjB,QAAQ,OAAO,CAAC;6BAGV,QAAQ,aAAa,CAAC;yCAGV,QAAQ,kBAAkB,EAAE,CAAC;;AAb1E,wBAgBE"}
1
+ {"version":3,"file":"ExpoLocalAuthentication.web.d.ts","sourceRoot":"","sources":["../src/ExpoLocalAuthentication.web.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;;wBAGpD,OAAO,CAAC,OAAO,CAAC;uBAGjB,OAAO,CAAC,OAAO,CAAC;6BAGV,OAAO,CAAC,aAAa,CAAC;yCAGV,OAAO,CAAC,kBAAkB,EAAE,CAAC;;AAV1E,wBAaE"}
@@ -1,8 +1,5 @@
1
1
  import { SecurityLevel } from './LocalAuthentication.types';
2
2
  export default {
3
- get name() {
4
- return 'ExpoLocalAuthentication';
5
- },
6
3
  async hasHardwareAsync() {
7
4
  return false;
8
5
  },
@@ -1 +1 @@
1
- {"version":3,"file":"ExpoLocalAuthentication.web.js","sourceRoot":"","sources":["../src/ExpoLocalAuthentication.web.ts"],"names":[],"mappings":"AAAA,OAAO,EAAsB,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAEhF,eAAe;IACb,IAAI,IAAI;QACN,OAAO,yBAAyB,CAAC;IACnC,CAAC;IACD,KAAK,CAAC,gBAAgB;QACpB,OAAO,KAAK,CAAC;IACf,CAAC;IACD,KAAK,CAAC,eAAe;QACnB,OAAO,KAAK,CAAC;IACf,CAAC;IACD,KAAK,CAAC,qBAAqB;QACzB,OAAO,aAAa,CAAC,IAAI,CAAC;IAC5B,CAAC;IACD,KAAK,CAAC,iCAAiC;QACrC,OAAO,EAAE,CAAC;IACZ,CAAC;CACF,CAAC","sourcesContent":["import { AuthenticationType, SecurityLevel } from './LocalAuthentication.types';\n\nexport default {\n get name(): string {\n return 'ExpoLocalAuthentication';\n },\n async hasHardwareAsync(): Promise<boolean> {\n return false;\n },\n async isEnrolledAsync(): Promise<boolean> {\n return false;\n },\n async getEnrolledLevelAsync(): Promise<SecurityLevel> {\n return SecurityLevel.NONE;\n },\n async supportedAuthenticationTypesAsync(): Promise<AuthenticationType[]> {\n return [];\n },\n};\n"]}
1
+ {"version":3,"file":"ExpoLocalAuthentication.web.js","sourceRoot":"","sources":["../src/ExpoLocalAuthentication.web.ts"],"names":[],"mappings":"AAAA,OAAO,EAAsB,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAEhF,eAAe;IACb,KAAK,CAAC,gBAAgB;QACpB,OAAO,KAAK,CAAC;IACf,CAAC;IACD,KAAK,CAAC,eAAe;QACnB,OAAO,KAAK,CAAC;IACf,CAAC;IACD,KAAK,CAAC,qBAAqB;QACzB,OAAO,aAAa,CAAC,IAAI,CAAC;IAC5B,CAAC;IACD,KAAK,CAAC,iCAAiC;QACrC,OAAO,EAAE,CAAC;IACZ,CAAC;CACF,CAAC","sourcesContent":["import { AuthenticationType, SecurityLevel } from './LocalAuthentication.types';\n\nexport default {\n async hasHardwareAsync(): Promise<boolean> {\n return false;\n },\n async isEnrolledAsync(): Promise<boolean> {\n return false;\n },\n async getEnrolledLevelAsync(): Promise<SecurityLevel> {\n return SecurityLevel.NONE;\n },\n async supportedAuthenticationTypesAsync(): Promise<AuthenticationType[]> {\n return [];\n },\n};\n"]}
@@ -1,5 +1,5 @@
1
- import { LocalAuthenticationOptions, AuthenticationType, LocalAuthenticationResult, SecurityLevel } from './LocalAuthentication.types';
2
- export { LocalAuthenticationOptions, AuthenticationType, LocalAuthenticationResult, SecurityLevel };
1
+ import { LocalAuthenticationOptions, AuthenticationType, LocalAuthenticationResult, SecurityLevel, BiometricsSecurityLevel } from './LocalAuthentication.types';
2
+ export { LocalAuthenticationOptions, AuthenticationType, LocalAuthenticationResult, SecurityLevel, BiometricsSecurityLevel, };
3
3
  /**
4
4
  * Determine whether a face or fingerprint scanner is available on the device.
5
5
  * @return Returns a promise which fulfils with a `boolean` value indicating whether a face or
@@ -1 +1 @@
1
- {"version":3,"file":"LocalAuthentication.d.ts","sourceRoot":"","sources":["../src/LocalAuthentication.ts"],"names":[],"mappings":"AAIA,OAAO,EACL,0BAA0B,EAC1B,kBAAkB,EAClB,yBAAyB,EACzB,aAAa,EACd,MAAM,6BAA6B,CAAC;AAErC,OAAO,EAAE,0BAA0B,EAAE,kBAAkB,EAAE,yBAAyB,EAAE,aAAa,EAAE,CAAC;AAGpG;;;;GAIG;AACH,wBAAsB,gBAAgB,IAAI,OAAO,CAAC,OAAO,CAAC,CAKzD;AAGD;;;;;;GAMG;AACH,wBAAsB,iCAAiC,IAAI,OAAO,CAAC,kBAAkB,EAAE,CAAC,CAKvF;AAGD;;;;GAIG;AACH,wBAAsB,eAAe,IAAI,OAAO,CAAC,OAAO,CAAC,CAKxD;AAGD;;;;;;GAMG;AACH,wBAAsB,qBAAqB,IAAI,OAAO,CAAC,aAAa,CAAC,CAKpE;AAGD;;;;;;;;GAQG;AACH,wBAAsB,iBAAiB,CACrC,OAAO,GAAE,0BAA+B,GACvC,OAAO,CAAC,yBAAyB,CAAC,CAgBpC;AAGD;;;GAGG;AACH,wBAAsB,kBAAkB,IAAI,OAAO,CAAC,IAAI,CAAC,CAKxD"}
1
+ {"version":3,"file":"LocalAuthentication.d.ts","sourceRoot":"","sources":["../src/LocalAuthentication.ts"],"names":[],"mappings":"AAIA,OAAO,EACL,0BAA0B,EAC1B,kBAAkB,EAClB,yBAAyB,EACzB,aAAa,EACb,uBAAuB,EACxB,MAAM,6BAA6B,CAAC;AAErC,OAAO,EACL,0BAA0B,EAC1B,kBAAkB,EAClB,yBAAyB,EACzB,aAAa,EACb,uBAAuB,GACxB,CAAC;AAGF;;;;GAIG;AACH,wBAAsB,gBAAgB,IAAI,OAAO,CAAC,OAAO,CAAC,CAKzD;AAGD;;;;;;GAMG;AACH,wBAAsB,iCAAiC,IAAI,OAAO,CAAC,kBAAkB,EAAE,CAAC,CAKvF;AAGD;;;;GAIG;AACH,wBAAsB,eAAe,IAAI,OAAO,CAAC,OAAO,CAAC,CAKxD;AAGD;;;;;;GAMG;AACH,wBAAsB,qBAAqB,IAAI,OAAO,CAAC,aAAa,CAAC,CAKpE;AAGD;;;;;;;;GAQG;AACH,wBAAsB,iBAAiB,CACrC,OAAO,GAAE,0BAA+B,GACvC,OAAO,CAAC,yBAAyB,CAAC,CAgBpC;AAGD;;;GAGG;AACH,wBAAsB,kBAAkB,IAAI,OAAO,CAAC,IAAI,CAAC,CAKxD"}
@@ -2,7 +2,7 @@ import { UnavailabilityError } from 'expo-modules-core';
2
2
  import invariant from 'invariant';
3
3
  import ExpoLocalAuthentication from './ExpoLocalAuthentication';
4
4
  import { AuthenticationType, SecurityLevel, } from './LocalAuthentication.types';
5
- export { AuthenticationType, SecurityLevel };
5
+ export { AuthenticationType, SecurityLevel, };
6
6
  // @needsAudit
7
7
  /**
8
8
  * Determine whether a face or fingerprint scanner is available on the device.
@@ -1 +1 @@
1
- {"version":3,"file":"LocalAuthentication.js","sourceRoot":"","sources":["../src/LocalAuthentication.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AACxD,OAAO,SAAS,MAAM,WAAW,CAAC;AAElC,OAAO,uBAAuB,MAAM,2BAA2B,CAAC;AAChE,OAAO,EAEL,kBAAkB,EAElB,aAAa,GACd,MAAM,6BAA6B,CAAC;AAErC,OAAO,EAA8B,kBAAkB,EAA6B,aAAa,EAAE,CAAC;AAEpG,cAAc;AACd;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB;IACpC,IAAI,CAAC,uBAAuB,CAAC,gBAAgB,EAAE;QAC7C,MAAM,IAAI,mBAAmB,CAAC,2BAA2B,EAAE,kBAAkB,CAAC,CAAC;KAChF;IACD,OAAO,MAAM,uBAAuB,CAAC,gBAAgB,EAAE,CAAC;AAC1D,CAAC;AAED,cAAc;AACd;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,iCAAiC;IACrD,IAAI,CAAC,uBAAuB,CAAC,iCAAiC,EAAE;QAC9D,MAAM,IAAI,mBAAmB,CAAC,2BAA2B,EAAE,mCAAmC,CAAC,CAAC;KACjG;IACD,OAAO,MAAM,uBAAuB,CAAC,iCAAiC,EAAE,CAAC;AAC3E,CAAC;AAED,cAAc;AACd;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe;IACnC,IAAI,CAAC,uBAAuB,CAAC,eAAe,EAAE;QAC5C,MAAM,IAAI,mBAAmB,CAAC,2BAA2B,EAAE,iBAAiB,CAAC,CAAC;KAC/E;IACD,OAAO,MAAM,uBAAuB,CAAC,eAAe,EAAE,CAAC;AACzD,CAAC;AAED,cAAc;AACd;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,qBAAqB;IACzC,IAAI,CAAC,uBAAuB,CAAC,qBAAqB,EAAE;QAClD,MAAM,IAAI,mBAAmB,CAAC,2BAA2B,EAAE,uBAAuB,CAAC,CAAC;KACrF;IACD,OAAO,MAAM,uBAAuB,CAAC,qBAAqB,EAAE,CAAC;AAC/D,CAAC;AAED,cAAc;AACd;;;;;;;;GAQG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACrC,UAAsC,EAAE;IAExC,IAAI,CAAC,uBAAuB,CAAC,iBAAiB,EAAE;QAC9C,MAAM,IAAI,mBAAmB,CAAC,2BAA2B,EAAE,mBAAmB,CAAC,CAAC;KACjF;IAED,IAAI,OAAO,CAAC,cAAc,CAAC,eAAe,CAAC,EAAE;QAC3C,SAAS,CACP,OAAO,OAAO,CAAC,aAAa,KAAK,QAAQ,IAAI,OAAO,CAAC,aAAa,CAAC,MAAM,EACzE,6FAA6F,CAC9F,CAAC;KACH;IAED,MAAM,aAAa,GAAG,OAAO,CAAC,aAAa,IAAI,cAAc,CAAC;IAC9D,MAAM,MAAM,GAAG,MAAM,uBAAuB,CAAC,iBAAiB,CAAC,EAAE,GAAG,OAAO,EAAE,aAAa,EAAE,CAAC,CAAC;IAE9F,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,cAAc;AACd;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,kBAAkB;IACtC,IAAI,CAAC,uBAAuB,CAAC,kBAAkB,EAAE;QAC/C,MAAM,IAAI,mBAAmB,CAAC,2BAA2B,EAAE,oBAAoB,CAAC,CAAC;KAClF;IACD,MAAM,uBAAuB,CAAC,kBAAkB,EAAE,CAAC;AACrD,CAAC","sourcesContent":["import { UnavailabilityError } from 'expo-modules-core';\nimport invariant from 'invariant';\n\nimport ExpoLocalAuthentication from './ExpoLocalAuthentication';\nimport {\n LocalAuthenticationOptions,\n AuthenticationType,\n LocalAuthenticationResult,\n SecurityLevel,\n} from './LocalAuthentication.types';\n\nexport { LocalAuthenticationOptions, AuthenticationType, LocalAuthenticationResult, SecurityLevel };\n\n// @needsAudit\n/**\n * Determine whether a face or fingerprint scanner is available on the device.\n * @return Returns a promise which fulfils with a `boolean` value indicating whether a face or\n * fingerprint scanner is available on this device.\n */\nexport async function hasHardwareAsync(): Promise<boolean> {\n if (!ExpoLocalAuthentication.hasHardwareAsync) {\n throw new UnavailabilityError('expo-local-authentication', 'hasHardwareAsync');\n }\n return await ExpoLocalAuthentication.hasHardwareAsync();\n}\n\n// @needsAudit\n/**\n * Determine what kinds of authentications are available on the device.\n * @return Returns a promise which fulfils to an array containing [`AuthenticationType`s](#authenticationtype).\n *\n * Devices can support multiple authentication methods- i.e. `[1,2]` means the device supports both\n * fingerprint and facial recognition. If none are supported, this method returns an empty array.\n */\nexport async function supportedAuthenticationTypesAsync(): Promise<AuthenticationType[]> {\n if (!ExpoLocalAuthentication.supportedAuthenticationTypesAsync) {\n throw new UnavailabilityError('expo-local-authentication', 'supportedAuthenticationTypesAsync');\n }\n return await ExpoLocalAuthentication.supportedAuthenticationTypesAsync();\n}\n\n// @needsAudit\n/**\n * Determine whether the device has saved fingerprints or facial data to use for authentication.\n * @return Returns a promise which fulfils to `boolean` value indicating whether the device has\n * saved fingerprints or facial data for authentication.\n */\nexport async function isEnrolledAsync(): Promise<boolean> {\n if (!ExpoLocalAuthentication.isEnrolledAsync) {\n throw new UnavailabilityError('expo-local-authentication', 'isEnrolledAsync');\n }\n return await ExpoLocalAuthentication.isEnrolledAsync();\n}\n\n// @needsAudit\n/**\n * Determine what kind of authentication is enrolled on the device.\n * @return Returns a promise which fulfils with [`SecurityLevel`](#securitylevel).\n * > **Note:** On Android devices prior to M, `SECRET` can be returned if only the SIM lock has been\n * enrolled, which is not the method that [`authenticateAsync`](#localauthenticationauthenticateasyncoptions)\n * prompts.\n */\nexport async function getEnrolledLevelAsync(): Promise<SecurityLevel> {\n if (!ExpoLocalAuthentication.getEnrolledLevelAsync) {\n throw new UnavailabilityError('expo-local-authentication', 'getEnrolledLevelAsync');\n }\n return await ExpoLocalAuthentication.getEnrolledLevelAsync();\n}\n\n// @needsAudit\n/**\n * Attempts to authenticate via Fingerprint/TouchID (or FaceID if available on the device).\n * > **Note:** Apple requires apps which use FaceID to provide a description of why they use this API.\n * If you try to use FaceID on an iPhone with FaceID without providing `infoPlist.NSFaceIDUsageDescription`\n * in `app.json`, the module will authenticate using device passcode. For more information about\n * usage descriptions on iOS, see [permissions guide](/guides/permissions/#ios).\n * @param options\n * @return Returns a promise which fulfils with [`LocalAuthenticationResult`](#localauthenticationresult).\n */\nexport async function authenticateAsync(\n options: LocalAuthenticationOptions = {}\n): Promise<LocalAuthenticationResult> {\n if (!ExpoLocalAuthentication.authenticateAsync) {\n throw new UnavailabilityError('expo-local-authentication', 'authenticateAsync');\n }\n\n if (options.hasOwnProperty('promptMessage')) {\n invariant(\n typeof options.promptMessage === 'string' && options.promptMessage.length,\n 'LocalAuthentication.authenticateAsync : `options.promptMessage` must be a non-empty string.'\n );\n }\n\n const promptMessage = options.promptMessage || 'Authenticate';\n const result = await ExpoLocalAuthentication.authenticateAsync({ ...options, promptMessage });\n\n return result;\n}\n\n// @needsAudit\n/**\n * Cancels authentication flow.\n * @platform android\n */\nexport async function cancelAuthenticate(): Promise<void> {\n if (!ExpoLocalAuthentication.cancelAuthenticate) {\n throw new UnavailabilityError('expo-local-authentication', 'cancelAuthenticate');\n }\n await ExpoLocalAuthentication.cancelAuthenticate();\n}\n"]}
1
+ {"version":3,"file":"LocalAuthentication.js","sourceRoot":"","sources":["../src/LocalAuthentication.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AACxD,OAAO,SAAS,MAAM,WAAW,CAAC;AAElC,OAAO,uBAAuB,MAAM,2BAA2B,CAAC;AAChE,OAAO,EAEL,kBAAkB,EAElB,aAAa,GAEd,MAAM,6BAA6B,CAAC;AAErC,OAAO,EAEL,kBAAkB,EAElB,aAAa,GAEd,CAAC;AAEF,cAAc;AACd;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB;IACpC,IAAI,CAAC,uBAAuB,CAAC,gBAAgB,EAAE,CAAC;QAC9C,MAAM,IAAI,mBAAmB,CAAC,2BAA2B,EAAE,kBAAkB,CAAC,CAAC;IACjF,CAAC;IACD,OAAO,MAAM,uBAAuB,CAAC,gBAAgB,EAAE,CAAC;AAC1D,CAAC;AAED,cAAc;AACd;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,iCAAiC;IACrD,IAAI,CAAC,uBAAuB,CAAC,iCAAiC,EAAE,CAAC;QAC/D,MAAM,IAAI,mBAAmB,CAAC,2BAA2B,EAAE,mCAAmC,CAAC,CAAC;IAClG,CAAC;IACD,OAAO,MAAM,uBAAuB,CAAC,iCAAiC,EAAE,CAAC;AAC3E,CAAC;AAED,cAAc;AACd;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe;IACnC,IAAI,CAAC,uBAAuB,CAAC,eAAe,EAAE,CAAC;QAC7C,MAAM,IAAI,mBAAmB,CAAC,2BAA2B,EAAE,iBAAiB,CAAC,CAAC;IAChF,CAAC;IACD,OAAO,MAAM,uBAAuB,CAAC,eAAe,EAAE,CAAC;AACzD,CAAC;AAED,cAAc;AACd;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,qBAAqB;IACzC,IAAI,CAAC,uBAAuB,CAAC,qBAAqB,EAAE,CAAC;QACnD,MAAM,IAAI,mBAAmB,CAAC,2BAA2B,EAAE,uBAAuB,CAAC,CAAC;IACtF,CAAC;IACD,OAAO,MAAM,uBAAuB,CAAC,qBAAqB,EAAE,CAAC;AAC/D,CAAC;AAED,cAAc;AACd;;;;;;;;GAQG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACrC,UAAsC,EAAE;IAExC,IAAI,CAAC,uBAAuB,CAAC,iBAAiB,EAAE,CAAC;QAC/C,MAAM,IAAI,mBAAmB,CAAC,2BAA2B,EAAE,mBAAmB,CAAC,CAAC;IAClF,CAAC;IAED,IAAI,OAAO,CAAC,cAAc,CAAC,eAAe,CAAC,EAAE,CAAC;QAC5C,SAAS,CACP,OAAO,OAAO,CAAC,aAAa,KAAK,QAAQ,IAAI,OAAO,CAAC,aAAa,CAAC,MAAM,EACzE,6FAA6F,CAC9F,CAAC;IACJ,CAAC;IAED,MAAM,aAAa,GAAG,OAAO,CAAC,aAAa,IAAI,cAAc,CAAC;IAC9D,MAAM,MAAM,GAAG,MAAM,uBAAuB,CAAC,iBAAiB,CAAC,EAAE,GAAG,OAAO,EAAE,aAAa,EAAE,CAAC,CAAC;IAE9F,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,cAAc;AACd;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,kBAAkB;IACtC,IAAI,CAAC,uBAAuB,CAAC,kBAAkB,EAAE,CAAC;QAChD,MAAM,IAAI,mBAAmB,CAAC,2BAA2B,EAAE,oBAAoB,CAAC,CAAC;IACnF,CAAC;IACD,MAAM,uBAAuB,CAAC,kBAAkB,EAAE,CAAC;AACrD,CAAC","sourcesContent":["import { UnavailabilityError } from 'expo-modules-core';\nimport invariant from 'invariant';\n\nimport ExpoLocalAuthentication from './ExpoLocalAuthentication';\nimport {\n LocalAuthenticationOptions,\n AuthenticationType,\n LocalAuthenticationResult,\n SecurityLevel,\n BiometricsSecurityLevel,\n} from './LocalAuthentication.types';\n\nexport {\n LocalAuthenticationOptions,\n AuthenticationType,\n LocalAuthenticationResult,\n SecurityLevel,\n BiometricsSecurityLevel,\n};\n\n// @needsAudit\n/**\n * Determine whether a face or fingerprint scanner is available on the device.\n * @return Returns a promise which fulfils with a `boolean` value indicating whether a face or\n * fingerprint scanner is available on this device.\n */\nexport async function hasHardwareAsync(): Promise<boolean> {\n if (!ExpoLocalAuthentication.hasHardwareAsync) {\n throw new UnavailabilityError('expo-local-authentication', 'hasHardwareAsync');\n }\n return await ExpoLocalAuthentication.hasHardwareAsync();\n}\n\n// @needsAudit\n/**\n * Determine what kinds of authentications are available on the device.\n * @return Returns a promise which fulfils to an array containing [`AuthenticationType`s](#authenticationtype).\n *\n * Devices can support multiple authentication methods- i.e. `[1,2]` means the device supports both\n * fingerprint and facial recognition. If none are supported, this method returns an empty array.\n */\nexport async function supportedAuthenticationTypesAsync(): Promise<AuthenticationType[]> {\n if (!ExpoLocalAuthentication.supportedAuthenticationTypesAsync) {\n throw new UnavailabilityError('expo-local-authentication', 'supportedAuthenticationTypesAsync');\n }\n return await ExpoLocalAuthentication.supportedAuthenticationTypesAsync();\n}\n\n// @needsAudit\n/**\n * Determine whether the device has saved fingerprints or facial data to use for authentication.\n * @return Returns a promise which fulfils to `boolean` value indicating whether the device has\n * saved fingerprints or facial data for authentication.\n */\nexport async function isEnrolledAsync(): Promise<boolean> {\n if (!ExpoLocalAuthentication.isEnrolledAsync) {\n throw new UnavailabilityError('expo-local-authentication', 'isEnrolledAsync');\n }\n return await ExpoLocalAuthentication.isEnrolledAsync();\n}\n\n// @needsAudit\n/**\n * Determine what kind of authentication is enrolled on the device.\n * @return Returns a promise which fulfils with [`SecurityLevel`](#securitylevel).\n * > **Note:** On Android devices prior to M, `SECRET` can be returned if only the SIM lock has been\n * enrolled, which is not the method that [`authenticateAsync`](#localauthenticationauthenticateasyncoptions)\n * prompts.\n */\nexport async function getEnrolledLevelAsync(): Promise<SecurityLevel> {\n if (!ExpoLocalAuthentication.getEnrolledLevelAsync) {\n throw new UnavailabilityError('expo-local-authentication', 'getEnrolledLevelAsync');\n }\n return await ExpoLocalAuthentication.getEnrolledLevelAsync();\n}\n\n// @needsAudit\n/**\n * Attempts to authenticate via Fingerprint/TouchID (or FaceID if available on the device).\n * > **Note:** Apple requires apps which use FaceID to provide a description of why they use this API.\n * If you try to use FaceID on an iPhone with FaceID without providing `infoPlist.NSFaceIDUsageDescription`\n * in `app.json`, the module will authenticate using device passcode. For more information about\n * usage descriptions on iOS, see [permissions guide](/guides/permissions/#ios).\n * @param options\n * @return Returns a promise which fulfils with [`LocalAuthenticationResult`](#localauthenticationresult).\n */\nexport async function authenticateAsync(\n options: LocalAuthenticationOptions = {}\n): Promise<LocalAuthenticationResult> {\n if (!ExpoLocalAuthentication.authenticateAsync) {\n throw new UnavailabilityError('expo-local-authentication', 'authenticateAsync');\n }\n\n if (options.hasOwnProperty('promptMessage')) {\n invariant(\n typeof options.promptMessage === 'string' && options.promptMessage.length,\n 'LocalAuthentication.authenticateAsync : `options.promptMessage` must be a non-empty string.'\n );\n }\n\n const promptMessage = options.promptMessage || 'Authenticate';\n const result = await ExpoLocalAuthentication.authenticateAsync({ ...options, promptMessage });\n\n return result;\n}\n\n// @needsAudit\n/**\n * Cancels authentication flow.\n * @platform android\n */\nexport async function cancelAuthenticate(): Promise<void> {\n if (!ExpoLocalAuthentication.cancelAuthenticate) {\n throw new UnavailabilityError('expo-local-authentication', 'cancelAuthenticate');\n }\n await ExpoLocalAuthentication.cancelAuthenticate();\n}\n"]}
@@ -31,9 +31,25 @@ export declare enum SecurityLevel {
31
31
  SECRET = 1,
32
32
  /**
33
33
  * Indicates biometric authentication.
34
+ * @deprecated please use `BIOMETRIC_STRONG` or `BIOMETRIC_WEAK` instead.
35
+ * @hidden
34
36
  */
35
- BIOMETRIC = 2
37
+ BIOMETRIC,
38
+ /**
39
+ * Indicates weak biometric authentication. For example, a 2D image-based face unlock.
40
+ * > There are currently no weak biometric authentication options on iOS.
41
+ */
42
+ BIOMETRIC_WEAK = 2,
43
+ /**
44
+ * Indicates strong biometric authentication. For example, a fingerprint scan or 3D face unlock.
45
+ */
46
+ BIOMETRIC_STRONG = 3
36
47
  }
48
+ /**
49
+ * Security level of the biometric authentication to allow.
50
+ * @platform android
51
+ */
52
+ export type BiometricsSecurityLevel = 'weak' | 'strong';
37
53
  export type LocalAuthenticationOptions = {
38
54
  /**
39
55
  * A message that is shown alongside the TouchID or FaceID prompt.
@@ -59,6 +75,14 @@ export type LocalAuthenticationOptions = {
59
75
  * @platform android
60
76
  */
61
77
  requireConfirmation?: boolean;
78
+ /**
79
+ * Sets the security class of biometric authentication to allow.
80
+ * `strong` allows only Android Class 3 biometrics. For example, a fingerprint or a 3D face scan.
81
+ * `weak` allows both Android Class 3 and Class 2 biometrics. Class 2 biometrics are less secure than Class 3. For example, a camera-based face unlock.
82
+ * @platform android
83
+ * @default 'weak'
84
+ */
85
+ biometricsSecurityLevel?: BiometricsSecurityLevel;
62
86
  /**
63
87
  * Allows to customize the default `Use Passcode` label shown after several failed
64
88
  * authentication attempts. Setting this option to an empty string disables this button from
@@ -1 +1 @@
1
- {"version":3,"file":"LocalAuthentication.types.d.ts","sourceRoot":"","sources":["../src/LocalAuthentication.types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,yBAAyB,GACjC;IAAE,OAAO,EAAE,IAAI,CAAA;CAAE,GACjB;IAAE,OAAO,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AAGxD,oBAAY,kBAAkB;IAC5B;;OAEG;IACH,WAAW,IAAI;IACf;;OAEG;IACH,kBAAkB,IAAI;IACtB;;;OAGG;IACH,IAAI,IAAI;CACT;AAGD,oBAAY,aAAa;IACvB;;OAEG;IACH,IAAI,IAAI;IACR;;OAEG;IACH,MAAM,IAAI;IACV;;OAEG;IACH,SAAS,IAAI;CACd;AAGD,MAAM,MAAM,0BAA0B,GAAG;IACvC;;OAEG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB;;OAEG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;;;;;OAOG;IACH,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC;;;;;OAKG;IACH,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B;;;;;OAKG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB,CAAC"}
1
+ {"version":3,"file":"LocalAuthentication.types.d.ts","sourceRoot":"","sources":["../src/LocalAuthentication.types.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,yBAAyB,GACjC;IAAE,OAAO,EAAE,IAAI,CAAA;CAAE,GACjB;IAAE,OAAO,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AAGxD,oBAAY,kBAAkB;IAC5B;;OAEG;IACH,WAAW,IAAI;IACf;;OAEG;IACH,kBAAkB,IAAI;IACtB;;;OAGG;IACH,IAAI,IAAI;CACT;AAGD,oBAAY,aAAa;IACvB;;OAEG;IACH,IAAI,IAAI;IACR;;OAEG;IACH,MAAM,IAAI;IACV;;;;OAIG;IACH,SAEkC;IAClC;;;OAGG;IACH,cAAc,IAAI;IAClB;;OAEG;IACH,gBAAgB,IAAI;CACrB;AAkBD;;;GAGG;AACH,MAAM,MAAM,uBAAuB,GAAG,MAAM,GAAG,QAAQ,CAAC;AAGxD,MAAM,MAAM,0BAA0B,GAAG;IACvC;;OAEG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB;;OAEG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;;;;;OAOG;IACH,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC;;;;;OAKG;IACH,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B;;;;;;OAMG;IACH,uBAAuB,CAAC,EAAE,uBAAuB,CAAC;IAClD;;;;;OAKG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB,CAAC"}
@@ -1,3 +1,4 @@
1
+ import { Platform } from 'expo-modules-core';
1
2
  // @needsAudit
2
3
  export var AuthenticationType;
3
4
  (function (AuthenticationType) {
@@ -28,7 +29,32 @@ export var SecurityLevel;
28
29
  SecurityLevel[SecurityLevel["SECRET"] = 1] = "SECRET";
29
30
  /**
30
31
  * Indicates biometric authentication.
32
+ * @deprecated please use `BIOMETRIC_STRONG` or `BIOMETRIC_WEAK` instead.
33
+ * @hidden
31
34
  */
32
- SecurityLevel[SecurityLevel["BIOMETRIC"] = 2] = "BIOMETRIC";
35
+ SecurityLevel[SecurityLevel["BIOMETRIC"] = Platform.OS === 'android'
36
+ ? SecurityLevel.BIOMETRIC_WEAK
37
+ : SecurityLevel.BIOMETRIC_STRONG] = "BIOMETRIC";
38
+ /**
39
+ * Indicates weak biometric authentication. For example, a 2D image-based face unlock.
40
+ * > There are currently no weak biometric authentication options on iOS.
41
+ */
42
+ SecurityLevel[SecurityLevel["BIOMETRIC_WEAK"] = 2] = "BIOMETRIC_WEAK";
43
+ /**
44
+ * Indicates strong biometric authentication. For example, a fingerprint scan or 3D face unlock.
45
+ */
46
+ SecurityLevel[SecurityLevel["BIOMETRIC_STRONG"] = 3] = "BIOMETRIC_STRONG";
33
47
  })(SecurityLevel || (SecurityLevel = {}));
48
+ Object.defineProperty(SecurityLevel, 'BIOMETRIC', {
49
+ get() {
50
+ const additionalMessage = Platform.OS === 'android'
51
+ ? '. `SecurityLevel.BIOMETRIC` is currently an alias for `SecurityLevel.BIOMETRIC_WEAK` on Android, which might lead to unexpected behaviour.'
52
+ : '';
53
+ console.warn('`SecurityLevel.BIOMETRIC` has been deprecated. Please use `SecurityLevel.BIOMETRIC_WEAK` or `SecurityLevel.BIOMETRIC_STRONG` instead' +
54
+ additionalMessage);
55
+ return Platform.OS === 'android'
56
+ ? SecurityLevel.BIOMETRIC_WEAK
57
+ : SecurityLevel.BIOMETRIC_STRONG;
58
+ },
59
+ });
34
60
  //# sourceMappingURL=LocalAuthentication.types.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"LocalAuthentication.types.js","sourceRoot":"","sources":["../src/LocalAuthentication.types.ts"],"names":[],"mappings":"AAIA,cAAc;AACd,MAAM,CAAN,IAAY,kBAcX;AAdD,WAAY,kBAAkB;IAC5B;;OAEG;IACH,yEAAe,CAAA;IACf;;OAEG;IACH,uFAAsB,CAAA;IACtB;;;OAGG;IACH,2DAAQ,CAAA;AACV,CAAC,EAdW,kBAAkB,KAAlB,kBAAkB,QAc7B;AAED,cAAc;AACd,MAAM,CAAN,IAAY,aAaX;AAbD,WAAY,aAAa;IACvB;;OAEG;IACH,iDAAQ,CAAA;IACR;;OAEG;IACH,qDAAU,CAAA;IACV;;OAEG;IACH,2DAAa,CAAA;AACf,CAAC,EAbW,aAAa,KAAb,aAAa,QAaxB","sourcesContent":["export type LocalAuthenticationResult =\n | { success: true }\n | { success: false; error: string; warning?: string };\n\n// @needsAudit\nexport enum AuthenticationType {\n /**\n * Indicates fingerprint support.\n */\n FINGERPRINT = 1,\n /**\n * Indicates facial recognition support.\n */\n FACIAL_RECOGNITION = 2,\n /**\n * Indicates iris recognition support.\n * @platform android\n */\n IRIS = 3,\n}\n\n// @needsAudit\nexport enum SecurityLevel {\n /**\n * Indicates no enrolled authentication.\n */\n NONE = 0,\n /**\n * Indicates non-biometric authentication (e.g. PIN, Pattern).\n */\n SECRET = 1,\n /**\n * Indicates biometric authentication.\n */\n BIOMETRIC = 2,\n}\n\n// @needsAudit\nexport type LocalAuthenticationOptions = {\n /**\n * A message that is shown alongside the TouchID or FaceID prompt.\n */\n promptMessage?: string;\n /**\n * Allows to customize the default `Cancel` label shown.\n */\n cancelLabel?: string;\n /**\n * After several failed attempts the system will fallback to the device passcode. This setting\n * allows you to disable this option and instead handle the fallback yourself. This can be\n * preferable in certain custom authentication workflows. This behaviour maps to using the iOS\n * [LAPolicyDeviceOwnerAuthenticationWithBiometrics](https://developer.apple.com/documentation/localauthentication/lapolicy/lapolicydeviceownerauthenticationwithbiometrics?language=objc)\n * policy rather than the [LAPolicyDeviceOwnerAuthentication](https://developer.apple.com/documentation/localauthentication/lapolicy/lapolicydeviceownerauthentication?language=objc)\n * policy. Defaults to `false`.\n */\n disableDeviceFallback?: boolean;\n /**\n * Sets a hint to the system for whether to require user confirmation after authentication.\n * This may be ignored by the system if the user has disabled implicit authentication in Settings\n * or if it does not apply to a particular biometric modality. Defaults to `true`.\n * @platform android\n */\n requireConfirmation?: boolean;\n /**\n * Allows to customize the default `Use Passcode` label shown after several failed\n * authentication attempts. Setting this option to an empty string disables this button from\n * showing in the prompt.\n * @platform ios\n */\n fallbackLabel?: string;\n};\n"]}
1
+ {"version":3,"file":"LocalAuthentication.types.js","sourceRoot":"","sources":["../src/LocalAuthentication.types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAM7C,cAAc;AACd,MAAM,CAAN,IAAY,kBAcX;AAdD,WAAY,kBAAkB;IAC5B;;OAEG;IACH,yEAAe,CAAA;IACf;;OAEG;IACH,uFAAsB,CAAA;IACtB;;;OAGG;IACH,2DAAQ,CAAA;AACV,CAAC,EAdW,kBAAkB,KAAlB,kBAAkB,QAc7B;AAED,cAAc;AACd,MAAM,CAAN,IAAY,aA0BX;AA1BD,WAAY,aAAa;IACvB;;OAEG;IACH,iDAAQ,CAAA;IACR;;OAEG;IACH,qDAAU,CAAA;IACV;;;;OAIG;IACH,2CAAY,QAAQ,CAAC,EAAE,KAAK,SAAS;QACnC,CAAC,CAAC,aAAa,CAAC,cAAc;QAC9B,CAAC,CAAC,aAAa,CAAC,gBAAgB,eAAA,CAAA;IAClC;;;OAGG;IACH,qEAAkB,CAAA;IAClB;;OAEG;IACH,yEAAoB,CAAA;AACtB,CAAC,EA1BW,aAAa,KAAb,aAAa,QA0BxB;AAED,MAAM,CAAC,cAAc,CAAC,aAAa,EAAE,WAAW,EAAE;IAChD,GAAG;QACD,MAAM,iBAAiB,GACrB,QAAQ,CAAC,EAAE,KAAK,SAAS;YACvB,CAAC,CAAC,4IAA4I;YAC9I,CAAC,CAAC,EAAE,CAAC;QACT,OAAO,CAAC,IAAI,CACV,sIAAsI;YACpI,iBAAiB,CACpB,CAAC;QACF,OAAO,QAAQ,CAAC,EAAE,KAAK,SAAS;YAC9B,CAAC,CAAC,aAAa,CAAC,cAAc;YAC9B,CAAC,CAAC,aAAa,CAAC,gBAAgB,CAAC;IACrC,CAAC;CACF,CAAC,CAAC","sourcesContent":["import { Platform } from 'expo-modules-core';\n\nexport type LocalAuthenticationResult =\n | { success: true }\n | { success: false; error: string; warning?: string };\n\n// @needsAudit\nexport enum AuthenticationType {\n /**\n * Indicates fingerprint support.\n */\n FINGERPRINT = 1,\n /**\n * Indicates facial recognition support.\n */\n FACIAL_RECOGNITION = 2,\n /**\n * Indicates iris recognition support.\n * @platform android\n */\n IRIS = 3,\n}\n\n// @needsAudit\nexport enum SecurityLevel {\n /**\n * Indicates no enrolled authentication.\n */\n NONE = 0,\n /**\n * Indicates non-biometric authentication (e.g. PIN, Pattern).\n */\n SECRET = 1,\n /**\n * Indicates biometric authentication.\n * @deprecated please use `BIOMETRIC_STRONG` or `BIOMETRIC_WEAK` instead.\n * @hidden\n */\n BIOMETRIC = Platform.OS === 'android'\n ? SecurityLevel.BIOMETRIC_WEAK\n : SecurityLevel.BIOMETRIC_STRONG,\n /**\n * Indicates weak biometric authentication. For example, a 2D image-based face unlock.\n * > There are currently no weak biometric authentication options on iOS.\n */\n BIOMETRIC_WEAK = 2,\n /**\n * Indicates strong biometric authentication. For example, a fingerprint scan or 3D face unlock.\n */\n BIOMETRIC_STRONG = 3,\n}\n\nObject.defineProperty(SecurityLevel, 'BIOMETRIC', {\n get() {\n const additionalMessage =\n Platform.OS === 'android'\n ? '. `SecurityLevel.BIOMETRIC` is currently an alias for `SecurityLevel.BIOMETRIC_WEAK` on Android, which might lead to unexpected behaviour.'\n : '';\n console.warn(\n '`SecurityLevel.BIOMETRIC` has been deprecated. Please use `SecurityLevel.BIOMETRIC_WEAK` or `SecurityLevel.BIOMETRIC_STRONG` instead' +\n additionalMessage\n );\n return Platform.OS === 'android'\n ? SecurityLevel.BIOMETRIC_WEAK\n : SecurityLevel.BIOMETRIC_STRONG;\n },\n});\n\n/**\n * Security level of the biometric authentication to allow.\n * @platform android\n */\nexport type BiometricsSecurityLevel = 'weak' | 'strong';\n\n// @needsAudit\nexport type LocalAuthenticationOptions = {\n /**\n * A message that is shown alongside the TouchID or FaceID prompt.\n */\n promptMessage?: string;\n /**\n * Allows to customize the default `Cancel` label shown.\n */\n cancelLabel?: string;\n /**\n * After several failed attempts the system will fallback to the device passcode. This setting\n * allows you to disable this option and instead handle the fallback yourself. This can be\n * preferable in certain custom authentication workflows. This behaviour maps to using the iOS\n * [LAPolicyDeviceOwnerAuthenticationWithBiometrics](https://developer.apple.com/documentation/localauthentication/lapolicy/lapolicydeviceownerauthenticationwithbiometrics?language=objc)\n * policy rather than the [LAPolicyDeviceOwnerAuthentication](https://developer.apple.com/documentation/localauthentication/lapolicy/lapolicydeviceownerauthentication?language=objc)\n * policy. Defaults to `false`.\n */\n disableDeviceFallback?: boolean;\n /**\n * Sets a hint to the system for whether to require user confirmation after authentication.\n * This may be ignored by the system if the user has disabled implicit authentication in Settings\n * or if it does not apply to a particular biometric modality. Defaults to `true`.\n * @platform android\n */\n requireConfirmation?: boolean;\n /**\n * Sets the security class of biometric authentication to allow.\n * `strong` allows only Android Class 3 biometrics. For example, a fingerprint or a 3D face scan.\n * `weak` allows both Android Class 3 and Class 2 biometrics. Class 2 biometrics are less secure than Class 3. For example, a camera-based face unlock.\n * @platform android\n * @default 'weak'\n */\n biometricsSecurityLevel?: BiometricsSecurityLevel;\n /**\n * Allows to customize the default `Use Passcode` label shown after several failed\n * authentication attempts. Setting this option to an empty string disables this button from\n * showing in the prompt.\n * @platform ios\n */\n fallbackLabel?: string;\n};\n"]}
@@ -10,17 +10,17 @@ Pod::Spec.new do |s|
10
10
  s.license = package['license']
11
11
  s.author = package['author']
12
12
  s.homepage = package['homepage']
13
- s.platform = :ios, '13.0'
13
+ s.platform = :ios, '13.4'
14
14
  s.swift_version = '5.4'
15
15
  s.source = { git: 'https://github.com/expo/expo.git' }
16
16
  s.static_framework = true
17
17
 
18
18
  s.dependency 'ExpoModulesCore'
19
19
 
20
- # Swift/Objective-C compatibility
21
- s.pod_target_xcconfig = {
22
- 'DEFINES_MODULE' => 'YES',
23
- 'SWIFT_COMPILATION_MODE' => 'wholemodule'
20
+ # Swift/Objective-C compatibility
21
+ s.pod_target_xcconfig = {
22
+ 'DEFINES_MODULE' => 'YES',
23
+ 'SWIFT_COMPILATION_MODE' => 'wholemodule'
24
24
  }
25
25
 
26
26
  if !$ExpoUseSources&.include?(package['name']) && ENV['EXPO_USE_SOURCE'].to_i == 0 && File.exist?("#{s.name}.xcframework") && Gem::Version.new(Pod::VERSION) >= Gem::Version.new('1.10.0')
@@ -165,5 +165,6 @@ enum AuthenticationType: Int {
165
165
  enum SecurityLevel: Int {
166
166
  case none = 0
167
167
  case secret = 1
168
- case biometric = 2
168
+ // We return any biometric as strong biometric, because there are currently no iOS devices with weak biometric options.
169
+ case biometric = 3
169
170
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "expo-local-authentication",
3
- "version": "13.7.0",
3
+ "version": "14.0.0",
4
4
  "description": "Provides an API for FaceID and TouchID (iOS) or the Fingerprint API (Android) to authenticate the user with a face or fingerprint scan.",
5
5
  "main": "build/LocalAuthentication.js",
6
6
  "types": "build/LocalAuthentication.d.ts",
@@ -46,5 +46,5 @@
46
46
  "peerDependencies": {
47
47
  "expo": "*"
48
48
  },
49
- "gitHead": "da25937e2a99661cbe5eb60ca1d8d6245fc96a50"
49
+ "gitHead": "4165b8d72e1b9a1889c2767534cc619e21468110"
50
50
  }
@@ -1,5 +1,5 @@
1
1
  import { ConfigPlugin } from 'expo/config-plugins';
2
2
  declare const _default: ConfigPlugin<void | {
3
- faceIDPermission?: string | undefined;
3
+ faceIDPermission?: string | false | undefined;
4
4
  }>;
5
5
  export default _default;
@@ -4,12 +4,11 @@ const config_plugins_1 = require("expo/config-plugins");
4
4
  const pkg = require('expo-local-authentication/package.json');
5
5
  const FACE_ID_USAGE = 'Allow $(PRODUCT_NAME) to use Face ID';
6
6
  const withLocalAuthentication = (config, { faceIDPermission } = {}) => {
7
- if (!config.ios)
8
- config.ios = {};
9
- if (!config.ios.infoPlist)
10
- config.ios.infoPlist = {};
11
- config.ios.infoPlist.NSFaceIDUsageDescription =
12
- faceIDPermission || config.ios.infoPlist.NSFaceIDUsageDescription || FACE_ID_USAGE;
7
+ config_plugins_1.IOSConfig.Permissions.createPermissionsPlugin({
8
+ NSFaceIDUsageDescription: FACE_ID_USAGE,
9
+ })(config, {
10
+ NSFaceIDUsageDescription: faceIDPermission,
11
+ });
13
12
  return config_plugins_1.AndroidConfig.Permissions.withPermissions(config, [
14
13
  'android.permission.USE_BIOMETRIC',
15
14
  'android.permission.USE_FINGERPRINT',
@@ -1,16 +1,17 @@
1
- import { AndroidConfig, ConfigPlugin, createRunOncePlugin } from 'expo/config-plugins';
1
+ import { AndroidConfig, ConfigPlugin, IOSConfig, createRunOncePlugin } from 'expo/config-plugins';
2
2
 
3
3
  const pkg = require('expo-local-authentication/package.json');
4
4
  const FACE_ID_USAGE = 'Allow $(PRODUCT_NAME) to use Face ID';
5
5
 
6
- const withLocalAuthentication: ConfigPlugin<{ faceIDPermission?: string } | void> = (
6
+ const withLocalAuthentication: ConfigPlugin<{ faceIDPermission?: string | false } | void> = (
7
7
  config,
8
8
  { faceIDPermission } = {}
9
9
  ) => {
10
- if (!config.ios) config.ios = {};
11
- if (!config.ios.infoPlist) config.ios.infoPlist = {};
12
- config.ios.infoPlist.NSFaceIDUsageDescription =
13
- faceIDPermission || config.ios.infoPlist.NSFaceIDUsageDescription || FACE_ID_USAGE;
10
+ IOSConfig.Permissions.createPermissionsPlugin({
11
+ NSFaceIDUsageDescription: FACE_ID_USAGE,
12
+ })(config, {
13
+ NSFaceIDUsageDescription: faceIDPermission,
14
+ });
14
15
 
15
16
  return AndroidConfig.Permissions.withPermissions(config, [
16
17
  'android.permission.USE_BIOMETRIC',
@@ -1,9 +1,6 @@
1
1
  import { AuthenticationType, SecurityLevel } from './LocalAuthentication.types';
2
2
 
3
3
  export default {
4
- get name(): string {
5
- return 'ExpoLocalAuthentication';
6
- },
7
4
  async hasHardwareAsync(): Promise<boolean> {
8
5
  return false;
9
6
  },
@@ -7,9 +7,16 @@ import {
7
7
  AuthenticationType,
8
8
  LocalAuthenticationResult,
9
9
  SecurityLevel,
10
+ BiometricsSecurityLevel,
10
11
  } from './LocalAuthentication.types';
11
12
 
12
- export { LocalAuthenticationOptions, AuthenticationType, LocalAuthenticationResult, SecurityLevel };
13
+ export {
14
+ LocalAuthenticationOptions,
15
+ AuthenticationType,
16
+ LocalAuthenticationResult,
17
+ SecurityLevel,
18
+ BiometricsSecurityLevel,
19
+ };
13
20
 
14
21
  // @needsAudit
15
22
  /**
@@ -1,3 +1,5 @@
1
+ import { Platform } from 'expo-modules-core';
2
+
1
3
  export type LocalAuthenticationResult =
2
4
  | { success: true }
3
5
  | { success: false; error: string; warning?: string };
@@ -31,10 +33,45 @@ export enum SecurityLevel {
31
33
  SECRET = 1,
32
34
  /**
33
35
  * Indicates biometric authentication.
36
+ * @deprecated please use `BIOMETRIC_STRONG` or `BIOMETRIC_WEAK` instead.
37
+ * @hidden
38
+ */
39
+ BIOMETRIC = Platform.OS === 'android'
40
+ ? SecurityLevel.BIOMETRIC_WEAK
41
+ : SecurityLevel.BIOMETRIC_STRONG,
42
+ /**
43
+ * Indicates weak biometric authentication. For example, a 2D image-based face unlock.
44
+ * > There are currently no weak biometric authentication options on iOS.
45
+ */
46
+ BIOMETRIC_WEAK = 2,
47
+ /**
48
+ * Indicates strong biometric authentication. For example, a fingerprint scan or 3D face unlock.
34
49
  */
35
- BIOMETRIC = 2,
50
+ BIOMETRIC_STRONG = 3,
36
51
  }
37
52
 
53
+ Object.defineProperty(SecurityLevel, 'BIOMETRIC', {
54
+ get() {
55
+ const additionalMessage =
56
+ Platform.OS === 'android'
57
+ ? '. `SecurityLevel.BIOMETRIC` is currently an alias for `SecurityLevel.BIOMETRIC_WEAK` on Android, which might lead to unexpected behaviour.'
58
+ : '';
59
+ console.warn(
60
+ '`SecurityLevel.BIOMETRIC` has been deprecated. Please use `SecurityLevel.BIOMETRIC_WEAK` or `SecurityLevel.BIOMETRIC_STRONG` instead' +
61
+ additionalMessage
62
+ );
63
+ return Platform.OS === 'android'
64
+ ? SecurityLevel.BIOMETRIC_WEAK
65
+ : SecurityLevel.BIOMETRIC_STRONG;
66
+ },
67
+ });
68
+
69
+ /**
70
+ * Security level of the biometric authentication to allow.
71
+ * @platform android
72
+ */
73
+ export type BiometricsSecurityLevel = 'weak' | 'strong';
74
+
38
75
  // @needsAudit
39
76
  export type LocalAuthenticationOptions = {
40
77
  /**
@@ -61,6 +98,14 @@ export type LocalAuthenticationOptions = {
61
98
  * @platform android
62
99
  */
63
100
  requireConfirmation?: boolean;
101
+ /**
102
+ * Sets the security class of biometric authentication to allow.
103
+ * `strong` allows only Android Class 3 biometrics. For example, a fingerprint or a 3D face scan.
104
+ * `weak` allows both Android Class 3 and Class 2 biometrics. Class 2 biometrics are less secure than Class 3. For example, a camera-based face unlock.
105
+ * @platform android
106
+ * @default 'weak'
107
+ */
108
+ biometricsSecurityLevel?: BiometricsSecurityLevel;
64
109
  /**
65
110
  * Allows to customize the default `Use Passcode` label shown after several failed
66
111
  * authentication attempts. Setting this option to an empty string disables this button from