diff --git a/.changeset/experimental-trusted-device-resources.md b/.changeset/experimental-trusted-device-resources.md new file mode 100644 index 00000000000..d7b667c7454 --- /dev/null +++ b/.changeset/experimental-trusted-device-resources.md @@ -0,0 +1,6 @@ +--- +'@clerk/clerk-js': minor +'@clerk/shared': minor +--- + +Add experimental APIs for biometric sign-in in native apps. This includes the `trusted_device` strategy for sign-in and session reverification, `nativeSettings` on the auth config, and `__experimental_` methods on `User` for managing biometric credentials. These may change in minor releases. diff --git a/.changeset/expo-biometrics-package.md b/.changeset/expo-biometrics-package.md new file mode 100644 index 00000000000..477025e85e1 --- /dev/null +++ b/.changeset/expo-biometrics-package.md @@ -0,0 +1,20 @@ +--- +'@clerk/expo': minor +'@clerk/expo-biometrics': minor +--- + +Introduce `@clerk/expo-biometrics`, a new package that `useBiometricCredentials()` now requires. Install it and rebuild your app: + +```sh +npx expo install @clerk/expo-biometrics +``` + +If it's missing, the hook throws an error with these same steps. + +Import the hook from `@clerk/expo/biometrics`: + +```ts +import { useBiometricCredentials } from '@clerk/expo/biometrics'; +``` + +Importing it from `@clerk/expo` still works, but it logs a deprecation warning and will be removed in the next major version. diff --git a/.github/workflows/expo-native-build.yml b/.github/workflows/expo-native-build.yml index bf96461fe88..c4f1573535b 100644 --- a/.github/workflows/expo-native-build.yml +++ b/.github/workflows/expo-native-build.yml @@ -10,6 +10,7 @@ on: - 'integration/templates/expo-native/**' - 'integration/tests/expo-native/**' - 'packages/expo/**' + - 'packages/expo-biometrics/**' - 'packages/expo-google-signin/**' workflow_dispatch: @@ -84,6 +85,7 @@ jobs: turbo.json \ packages/clerk-js \ packages/expo \ + packages/expo-biometrics \ packages/expo-google-signin \ packages/react \ packages/shared \ @@ -121,10 +123,11 @@ jobs: - name: Build and pack Clerk packages if: steps.native-build-cache.outputs.cache-hit != 'true' run: | - pnpm --filter @clerk/expo... build + pnpm --filter @clerk/expo... --filter @clerk/expo-biometrics build mkdir -p "$SDK_PACK_DIR" pnpm --filter @clerk/expo pack --pack-destination "$SDK_PACK_DIR" pnpm --filter @clerk/expo-google-signin pack --pack-destination "$SDK_PACK_DIR" + pnpm --filter @clerk/expo-biometrics pack --pack-destination "$SDK_PACK_DIR" - name: Install fixture dependencies if: steps.native-build-cache.outputs.cache-hit != 'true' @@ -138,7 +141,8 @@ jobs: # [0-9] keeps this glob off the clerk-expo-google-signin tarball. SDK_TARBALL="$(ls "$SDK_PACK_DIR"/clerk-expo-[0-9]*.tgz)" GOOGLE_SIGNIN_TARBALL="$(ls "$SDK_PACK_DIR"/clerk-expo-google-signin-*.tgz)" - pnpm add "$SDK_TARBALL" "$GOOGLE_SIGNIN_TARBALL" -w + BIOMETRICS_TARBALL="$(ls "$SDK_PACK_DIR"/clerk-expo-biometrics-*.tgz)" + pnpm add "$SDK_TARBALL" "$GOOGLE_SIGNIN_TARBALL" "$BIOMETRICS_TARBALL" -w # expo-dev-client makes even release builds boot into the dev # launcher (unreachable Metro in CI), which stalls every Maestro # flow on a blank screen. Skip it on e2e jobs only. @@ -209,6 +213,15 @@ jobs: working-directory: ${{ env.FIXTURE_DIR }} run: pnpm build:android + # The module's Robolectric tests need an Expo host project for expo-modules-core, so they run in the fixture. + # The packed module leaves out its tests, so they are copied in from the repo. + - name: Test expo-biometrics Android module + if: matrix.platform == 'android' && steps.native-build-cache.outputs.cache-hit != 'true' + working-directory: ${{ env.FIXTURE_DIR }}/android + run: | + cp -R "$GITHUB_WORKSPACE/packages/expo-biometrics/android/src/test" "$(readlink -f ../node_modules/@clerk/expo-biometrics)/android/src/" + ./gradlew :clerk-expo-biometrics:testDebugUnitTest + - name: Prebuild iOS fixture if: matrix.platform == 'ios' && steps.native-build-cache.outputs.cache-hit != 'true' working-directory: ${{ env.FIXTURE_DIR }} diff --git a/integration/templates/expo-native/App.tsx b/integration/templates/expo-native/App.tsx index 11d3670243a..bfac480af41 100644 --- a/integration/templates/expo-native/App.tsx +++ b/integration/templates/expo-native/App.tsx @@ -4,6 +4,7 @@ import { tokenCache } from '@clerk/expo/token-cache'; import { useState } from 'react'; import { Button, Modal, StyleSheet, Text, View } from 'react-native'; +import { BiometricAvailabilityButton } from './components/BiometricAvailabilityButton'; import { GoogleSignInButton } from './components/GoogleSignInButton'; const publishableKey = process.env.EXPO_PUBLIC_CLERK_PUBLISHABLE_KEY; @@ -64,6 +65,7 @@ function NativeBuildFixture() { onPress={() => setIsAuthOpen(true)} /> {!isSignedIn && } + {!isSignedIn && } {isSignedIn && (