@symbiote-native/local-auth 3.0.1 → 3.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +33 -24
- package/package.json +15 -15
package/README.md
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
# @symbiote-native/local-auth
|
|
2
2
|
|
|
3
3
|
A wrapper package for [SymbioteNative](../../README.md) that makes
|
|
4
|
-
[`expo-local-authentication`](https://github.com/expo/expo/tree/main/packages/expo-local-authentication)
|
|
5
|
-
|
|
4
|
+
[`expo-local-authentication`](https://github.com/expo/expo/tree/main/packages/expo-local-authentication):
|
|
5
|
+
FaceID/TouchID on iOS, the Fingerprint/Biometric API on Android - usable from **every**
|
|
6
6
|
adapter, React, Vue, Svelte, Solid, and Angular, not just React. Unlike this repo's other Expo wrapper
|
|
7
7
|
([`@symbiote-native/sensors`](../sensors), an `EventEmitter` + live-subscription surface),
|
|
8
8
|
every function here is a one-shot async call with no per-instance state, so there is no hook/
|
|
9
|
-
composable/service to wrap
|
|
9
|
+
composable/service to wrap - the React, Vue, Svelte, Solid, and Angular entry points are plain
|
|
10
10
|
re-exports of the same `core`.
|
|
11
11
|
|
|
12
12
|
## Install
|
|
@@ -23,44 +23,44 @@ npx @symbiote-native/cli new my-app --local-auth
|
|
|
23
23
|
npx @symbiote-native/cli add --local-auth
|
|
24
24
|
```
|
|
25
25
|
|
|
26
|
-
Either way: installs `@symbiote-native/local-auth` and wires the native autolinking automatically
|
|
26
|
+
Either way: installs `@symbiote-native/local-auth` and wires the native autolinking automatically - see
|
|
27
27
|
[`@symbiote-native/cli`](../cli).
|
|
28
28
|
|
|
29
29
|
<details>
|
|
30
|
-
<summary>Manual install (no CLI
|
|
30
|
+
<summary>Manual install (no CLI - installing and wiring native autolinking by hand)</summary>
|
|
31
31
|
|
|
32
32
|
```bash
|
|
33
33
|
npm install @symbiote-native/local-auth
|
|
34
34
|
```
|
|
35
35
|
|
|
36
36
|
`expo-local-authentication` and `expo-modules-core` come along as regular dependencies, pinned
|
|
37
|
-
to exact versions
|
|
37
|
+
to exact versions - never install either yourself, and never add the `expo` meta-package to
|
|
38
38
|
your project (it bundles its own Metro/Babel pipeline, which conflicts with this project's own).
|
|
39
39
|
|
|
40
40
|
## Required one-time step: native autolinking wiring
|
|
41
41
|
|
|
42
42
|
Unlike a plain RN native module, `expo-local-authentication`'s native code is discovered by
|
|
43
|
-
`expo-modules-autolinking`, not RN's own `react-native.config.cjs` mechanism
|
|
43
|
+
`expo-modules-autolinking`, not RN's own `react-native.config.cjs` mechanism - this needs wiring
|
|
44
44
|
into the native host app **once**, covering this package and every other
|
|
45
45
|
`expo-modules-core` package with zero further changes:
|
|
46
46
|
|
|
47
47
|
| Platform | Touches |
|
|
48
48
|
| -------- | --------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
49
|
-
| iOS | `ios/Podfile`
|
|
50
|
-
| iOS | `AppDelegate.swift`
|
|
51
|
-
| Android | `settings.gradle` / `app/build.gradle`
|
|
52
|
-
| Android | `MainApplication.kt`
|
|
49
|
+
| iOS | `ios/Podfile` - add `use_expo_modules!` |
|
|
50
|
+
| iOS | `AppDelegate.swift` - Expo's runtime-bootstrap hook |
|
|
51
|
+
| Android | `settings.gradle` / `app/build.gradle` - resolve and include the Expo Gradle projects |
|
|
52
|
+
| Android | `MainApplication.kt` - Expo's bootstrap hook, plus a hand-written native-module name map (there's no `expo` meta-package here to auto-generate one) |
|
|
53
53
|
|
|
54
54
|
Full mechanics live in the `symbiote-expo-native-module` project skill. Reference
|
|
55
55
|
implementation: `examples/expo-react/ios/Podfile` and
|
|
56
56
|
`examples/expo-react/android/app/src/main/java/com/canaryexpo/MainApplication.kt`.
|
|
57
57
|
|
|
58
|
-
Two platform permission strings ship with the native module itself
|
|
58
|
+
Two platform permission strings ship with the native module itself - nothing to reimplement,
|
|
59
59
|
just add the strings your app's own Info.plist/manifest needs:
|
|
60
60
|
|
|
61
|
-
- iOS
|
|
61
|
+
- iOS - `NSFaceIDUsageDescription` in `Info.plist` (without it, iOS silently falls back to the
|
|
62
62
|
device passcode instead of prompting FaceID).
|
|
63
|
-
- Android
|
|
63
|
+
- Android - `USE_BIOMETRIC` in `AndroidManifest.xml`.
|
|
64
64
|
|
|
65
65
|
</details>
|
|
66
66
|
|
|
@@ -72,11 +72,11 @@ src/core/ hasHardwareAsync / isEnrolledAsync / getEnrolledLevelAsync /
|
|
|
72
72
|
AuthenticationType, SecurityLevel, and the option/result/error types.
|
|
73
73
|
native-module.ts resolves the native module via expo-modules-core's
|
|
74
74
|
requireNativeModule.
|
|
75
|
-
src/angular/ @symbiote-native/local-auth/angular
|
|
75
|
+
src/angular/ @symbiote-native/local-auth/angular - export * from '../core'
|
|
76
76
|
```
|
|
77
77
|
|
|
78
78
|
`./react`, `./vue`, `./svelte`, and `./solid` are `exports`-map aliases straight onto
|
|
79
|
-
`src/core/`
|
|
79
|
+
`src/core/` - no physical per-framework file, since there's nothing to subscribe to or clean up.
|
|
80
80
|
`./angular` stays a physical file/subpath since Angular ships through a separate `ngc`/AOT build
|
|
81
81
|
(`build-ngc/`).
|
|
82
82
|
|
|
@@ -349,7 +349,7 @@ export class LocalAuthScreen {
|
|
|
349
349
|
}
|
|
350
350
|
```
|
|
351
351
|
|
|
352
|
-
There's no per-instance service to `inject()` in the Angular case
|
|
352
|
+
There's no per-instance service to `inject()` in the Angular case - every function is a plain
|
|
353
353
|
free function off the core package, called straight from the constructor. The examples above are
|
|
354
354
|
trimmed from the real canary demo screens, which exist for all six Expo canaries
|
|
355
355
|
(`examples/expo-react/screens/LocalAuthScreen.tsx`,
|
|
@@ -360,7 +360,7 @@ trimmed from the real canary demo screens, which exist for all six Expo canaries
|
|
|
360
360
|
|
|
361
361
|
## API
|
|
362
362
|
|
|
363
|
-
Free functions, no event stream, no per-instance state
|
|
363
|
+
Free functions, no event stream, no per-instance state - upstream ships a handful of async
|
|
364
364
|
functions and two enums, not a subscribable sensor, so the React/Vue/Svelte/Solid/Angular entry
|
|
365
365
|
points above are plain re-exports of `core` with nothing adapter-specific to add.
|
|
366
366
|
|
|
@@ -374,7 +374,7 @@ cancelAuthenticate(): Promise<void> // Android only
|
|
|
374
374
|
```
|
|
375
375
|
|
|
376
376
|
Plus `AuthenticationType`, `SecurityLevel`, `ILocalAuthenticationOptions`,
|
|
377
|
-
`ILocalAuthenticationResult`, `ILocalAuthenticationError`, `IBiometricsSecurityLevel`
|
|
377
|
+
`ILocalAuthenticationResult`, `ILocalAuthenticationError`, `IBiometricsSecurityLevel` - ported
|
|
378
378
|
from upstream's `LocalAuthentication.types.ts`, renamed with this repo's `I`-prefix convention
|
|
379
379
|
for exported types (`ts-js-best-practices`).
|
|
380
380
|
|
|
@@ -383,7 +383,7 @@ import {
|
|
|
383
383
|
authenticateAsync,
|
|
384
384
|
hasHardwareAsync,
|
|
385
385
|
} from '@symbiote-native/local-auth';
|
|
386
|
-
// or the framework-scoped entry points
|
|
386
|
+
// or the framework-scoped entry points - identical surface, re-exported verbatim:
|
|
387
387
|
import { authenticateAsync } from '@symbiote-native/local-auth/react';
|
|
388
388
|
import { authenticateAsync } from '@symbiote-native/local-auth/vue';
|
|
389
389
|
import { authenticateAsync } from '@symbiote-native/local-auth/svelte';
|
|
@@ -397,7 +397,7 @@ import { authenticateAsync } from '@symbiote-native/local-auth/angular';
|
|
|
397
397
|
pattern, or password set.** A real symptom on a fresh emulator or factory-reset device:
|
|
398
398
|
`authenticateAsync` resolves `{ success: false, error: 'not_enrolled', warning:
|
|
399
399
|
'KeyguardManager#isDeviceSecure() returned false' }`. This is **not** a missing app
|
|
400
|
-
permission
|
|
400
|
+
permission - the manifest permission this package needs is an ordinary build-time merge with
|
|
401
401
|
no runtime prompt, so there's nothing for your app to request. The fix lives on the device:
|
|
402
402
|
Settings → Security → Screen lock → set a PIN/pattern/password, then optionally enroll a
|
|
403
403
|
fingerprint (Extended Controls → Fingerprint on an emulator) to exercise the biometric path
|
|
@@ -406,17 +406,26 @@ import { authenticateAsync } from '@symbiote-native/local-auth/angular';
|
|
|
406
406
|
requires apps using FaceID to declare why (`Info.plist`); skip it and `authenticateAsync`
|
|
407
407
|
still resolves, just via the passcode prompt instead of FaceID.
|
|
408
408
|
|
|
409
|
+
## Common questions
|
|
410
|
+
|
|
411
|
+
- **Face ID falls back to the passcode.** `NSFaceIDUsageDescription` is missing from Info.plist.
|
|
412
|
+
- **Check before prompting?** `hasHardwareAsync` and `isEnrolledAsync` must both be true.
|
|
413
|
+
- **Customize the prompt?** `promptMessage`, `cancelLabel`, `fallbackLabel`, `disableDeviceFallback`.
|
|
414
|
+
|
|
415
|
+
Sources: [Expo docs: LocalAuthentication](https://docs.expo.dev/versions/latest/sdk/local-authentication/),
|
|
416
|
+
[expo/expo#25055](https://github.com/expo/expo/issues/25055).
|
|
417
|
+
|
|
409
418
|
## Test it
|
|
410
419
|
|
|
411
|
-
No Fabric/Descriptor angle at all
|
|
420
|
+
No Fabric/Descriptor angle at all - every function here is a pure async-function surface, never
|
|
412
421
|
a view or per-instance state. Tests inject a fake native-module object in place of the real
|
|
413
422
|
`requireNativeModule` resolution (`src/core/local-authentication.test.ts`,
|
|
414
|
-
`src/core/types.test.ts`, `vitest`)
|
|
423
|
+
`src/core/types.test.ts`, `vitest`) - no `installFabric()`, no ViewConfig. Native rendering itself
|
|
415
424
|
is verified on-device (see the parent [README](../../README.md) for the project's testing model).
|
|
416
425
|
|
|
417
426
|
Native autolinking wiring is done in all six Expo canary apps
|
|
418
427
|
(`examples/expo-react`, `examples/expo-vue-sfc`, `examples/expo-vue-tsx`, `examples/expo-svelte`,
|
|
419
|
-
`examples/expo-solid`, `examples/expo-angular`)
|
|
428
|
+
`examples/expo-solid`, `examples/expo-angular`) - iOS Podfile/`AppDelegate.swift` +
|
|
420
429
|
`NSFaceIDUsageDescription`, Android Gradle/`MainApplication.kt` + `USE_BIOMETRIC`, all six
|
|
421
430
|
confirmed present. The one remaining gap: this package isn't yet demoed in the plain, non-Expo
|
|
422
431
|
`examples/react`/`vue-sfc`/`vue-tsx`/`svelte`/`solid`/`angular` canaries, since an
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@symbiote-native/local-auth",
|
|
3
|
-
"version": "3.0.
|
|
3
|
+
"version": "3.0.3",
|
|
4
4
|
"description": "expo-local-authentication wrapped for SymbioteNative — one framework-agnostic core, built once and reachable from the React, Vue, Svelte, Solid, and Angular adapters. FaceID/TouchID on iOS, the Fingerprint/Biometric API on Android.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -70,7 +70,7 @@
|
|
|
70
70
|
},
|
|
71
71
|
"dependencies": {
|
|
72
72
|
"expo-local-authentication": "57.0.2",
|
|
73
|
-
"expo-modules-core": "57.0.
|
|
73
|
+
"expo-modules-core": "57.0.20",
|
|
74
74
|
"invariant": "^2.2.4"
|
|
75
75
|
},
|
|
76
76
|
"peerDependencies": {
|
|
@@ -81,12 +81,12 @@
|
|
|
81
81
|
"solid-js": ">=1.9.0",
|
|
82
82
|
"svelte": ">=5.56.0",
|
|
83
83
|
"vue": ">=3.5.0",
|
|
84
|
-
"@symbiote-native/angular": "^3.
|
|
85
|
-
"@symbiote-native/engine": "^1.
|
|
86
|
-
"@symbiote-native/react": "^3.0
|
|
87
|
-
"@symbiote-native/solid": "^3.0
|
|
88
|
-
"@symbiote-native/svelte": "^3.0
|
|
89
|
-
"@symbiote-native/vue": "^3.0
|
|
84
|
+
"@symbiote-native/angular": "^3.2.0",
|
|
85
|
+
"@symbiote-native/engine": "^1.5.0",
|
|
86
|
+
"@symbiote-native/react": "^3.2.0",
|
|
87
|
+
"@symbiote-native/solid": "^3.1.0",
|
|
88
|
+
"@symbiote-native/svelte": "^3.1.0",
|
|
89
|
+
"@symbiote-native/vue": "^3.2.0"
|
|
90
90
|
},
|
|
91
91
|
"peerDependenciesMeta": {
|
|
92
92
|
"@symbiote-native/angular": {
|
|
@@ -135,13 +135,13 @@
|
|
|
135
135
|
"solid-js": "^1.9.14",
|
|
136
136
|
"svelte": "^5.56.0",
|
|
137
137
|
"typescript": "~6.0.0",
|
|
138
|
-
"@symbiote-native/angular": "3.
|
|
139
|
-
"@symbiote-native/engine": "1.
|
|
140
|
-
"@symbiote-native/react": "3.0
|
|
141
|
-
"@symbiote-native/solid": "3.0
|
|
142
|
-
"@symbiote-native/svelte": "3.0
|
|
143
|
-
"@symbiote-native/test-utils": "0.4.
|
|
144
|
-
"@symbiote-native/vue": "3.0
|
|
138
|
+
"@symbiote-native/angular": "3.2.0",
|
|
139
|
+
"@symbiote-native/engine": "1.5.0",
|
|
140
|
+
"@symbiote-native/react": "3.2.0",
|
|
141
|
+
"@symbiote-native/solid": "3.1.0",
|
|
142
|
+
"@symbiote-native/svelte": "3.1.0",
|
|
143
|
+
"@symbiote-native/test-utils": "0.4.6",
|
|
144
|
+
"@symbiote-native/vue": "3.2.0"
|
|
145
145
|
},
|
|
146
146
|
"scripts": {
|
|
147
147
|
"typecheck": "tsc --build",
|