Skip to content

Commit

Permalink
Merge pull request #1209 from andrew-bierman/Add-biometric-authentica…
Browse files Browse the repository at this point in the history
…tion
  • Loading branch information
andrew-bierman authored Sep 2, 2024
2 parents 96ba688 + f9f1570 commit c5023ff
Show file tree
Hide file tree
Showing 3 changed files with 77 additions and 3 deletions.
1 change: 1 addition & 0 deletions apps/expo/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@
"expo-image-picker": "~14.7.1",
"expo-linear-gradient": "~12.7.2",
"expo-linking": "~6.2.2",
"expo-local-authentication": "~13.8.0",
"expo-location": "~16.5.5",
"expo-random": "~13.6.0",
"expo-router": "~3.4.10",
Expand Down
67 changes: 64 additions & 3 deletions packages/app/modules/auth/components/AuthWrapper.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import React from 'react';
import React, { useEffect, useState } from 'react';
import { AuthLoader } from './AuthLoader';
import { Redirect } from 'app/components/Redirect';
import { RSpinner, RText } from '@packrat/ui';
import { Platform, View } from 'react-native';
import { RSpinner, RText, RButton } from '@packrat/ui';
import { Platform, View, Alert } from 'react-native';
import LandingPage from 'app/components/landing_page';
import * as LocalAuthentication from 'expo-local-authentication';
import useTheme from 'app/hooks/useTheme';

interface AuthWrapperProps {
children?: React.ReactNode;
Expand All @@ -14,6 +16,65 @@ export const AuthWrapper = ({
children,
unauthorizedElement,
}: AuthWrapperProps) => {
const [isAuthenticated, setIsAuthenticated] = useState(false);
const { currentTheme } = useTheme();

const authenticate = async () => {
if (Platform.OS === 'web') {
setIsAuthenticated(true);
return;
}

const hasHardware = await LocalAuthentication.hasHardwareAsync();
if (!hasHardware) {
Alert.alert(
'Error',
'Your device does not support biometric authentication.',
);
return;
}

const hasBiometrics = await LocalAuthentication.isEnrolledAsync();
if (!hasBiometrics) {
Alert.alert(
'Error',
'No biometrics are enrolled. Please set up biometrics in your device settings.',
);
return;
}

const result = await LocalAuthentication.authenticateAsync({
promptMessage: 'Authenticate to continue',
fallbackLabel: 'Use Passcode',
});

if (result.success) {
setIsAuthenticated(true);
}
};

useEffect(() => {
authenticate();
}, []);

if (!isAuthenticated) {
return (
<View
style={{
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: currentTheme.colors.background,
}}
>
<RText style={{ color: currentTheme.colors.text }}>
Please unlock to continue
</RText>
<RButton onPress={authenticate}>Unlock</RButton>
</View>
);
}

const loadingElement =
Platform.OS === 'web' ? (
<RText>Loading...</RText>
Expand Down
12 changes: 12 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -20846,6 +20846,7 @@ __metadata:
expo-image-picker: "npm:~14.7.1"
expo-linear-gradient: "npm:~12.7.2"
expo-linking: "npm:~6.2.2"
expo-local-authentication: "npm:~13.8.0"
expo-location: "npm:~16.5.5"
expo-random: "npm:~13.6.0"
expo-router: "npm:~3.4.10"
Expand Down Expand Up @@ -21162,6 +21163,17 @@ __metadata:
languageName: node
linkType: hard

"expo-local-authentication@npm:~13.8.0":
version: 13.8.0
resolution: "expo-local-authentication@npm:13.8.0"
dependencies:
invariant: "npm:^2.2.4"
peerDependencies:
expo: "*"
checksum: 10/06ad68d96831058e51115fa398479faba9b4059564ecc44ee7eef739be7c5df1c632ec0138e008549dc2e7cd4a8eed9830d30ffb8ae97431e17f7ab8b2d55f87
languageName: node
linkType: hard

"expo-location@npm:~16.5.5":
version: 16.5.5
resolution: "expo-location@npm:16.5.5"
Expand Down

0 comments on commit c5023ff

Please sign in to comment.