mirror of
https://github.com/aliasvault/aliasvault.git
synced 2026-04-05 07:14:15 -04:00
Refactor AuthContext to return translation keys instead of direct translations (#1085)
This commit is contained in:
@@ -26,7 +26,7 @@ export default function SettingsScreen() : React.ReactNode {
|
||||
const webApi = useWebApi();
|
||||
const colors = useColors();
|
||||
const { t } = useTranslation();
|
||||
const { getAuthMethodDisplay, shouldShowAutofillReminder } = useAuth();
|
||||
const { getAuthMethodDisplayKey, shouldShowAutofillReminder } = useAuth();
|
||||
const { getAutoLockTimeout } = useAuth();
|
||||
const { loadApiUrl, getDisplayUrl } = useApiUrl();
|
||||
const scrollY = useRef(new Animated.Value(0)).current;
|
||||
@@ -69,8 +69,8 @@ export default function SettingsScreen() : React.ReactNode {
|
||||
* Load the auth method display.
|
||||
*/
|
||||
const loadAuthMethodDisplay = async () : Promise<void> => {
|
||||
const authMethod = await getAuthMethodDisplay();
|
||||
setAuthMethodDisplay(authMethod);
|
||||
const authMethodKey = await getAuthMethodDisplayKey();
|
||||
setAuthMethodDisplay(t(authMethodKey));
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -82,7 +82,7 @@ export default function SettingsScreen() : React.ReactNode {
|
||||
};
|
||||
|
||||
loadData();
|
||||
}, [getAutoLockTimeout, getAuthMethodDisplay, setIsFirstLoad, loadApiUrl, t])
|
||||
}, [getAutoLockTimeout, getAuthMethodDisplayKey, setIsFirstLoad, loadApiUrl, t])
|
||||
);
|
||||
|
||||
/**
|
||||
|
||||
@@ -18,10 +18,10 @@ export default function VaultUnlockSettingsScreen() : React.ReactNode {
|
||||
const colors = useColors();
|
||||
const { t } = useTranslation();
|
||||
const [initialized, setInitialized] = useState(false);
|
||||
const { setAuthMethods, getEnabledAuthMethods, getBiometricDisplayName } = useAuth();
|
||||
const { setAuthMethods, getEnabledAuthMethods, getBiometricDisplayNameKey } = useAuth();
|
||||
const [hasBiometrics, setHasBiometrics] = useState(false);
|
||||
const [isBiometricsEnabled, setIsBiometricsEnabled] = useState(false);
|
||||
const [biometricDisplayName, setBiometricDisplayName] = useState(Platform.OS === 'ios' ? t('settings.vaultUnlockSettings.faceIdTouchId') : t('settings.vaultUnlockSettings.biometrics'));
|
||||
const [biometricDisplayName, setBiometricDisplayName] = useState('');
|
||||
const [_, setEnabledAuthMethods] = useState<AuthMethod[]>([]);
|
||||
|
||||
useEffect(() => {
|
||||
@@ -40,8 +40,10 @@ export default function VaultUnlockSettingsScreen() : React.ReactNode {
|
||||
const isBiometricAvailable = compatible && enrolled;
|
||||
setHasBiometrics(isBiometricAvailable);
|
||||
|
||||
// Get appropriate display name
|
||||
const displayName = Platform.OS === 'ios' ? await getBiometricDisplayName() : t('settings.vaultUnlockSettings.biometrics');
|
||||
// Get appropriate display name key from auth context
|
||||
const displayNameKey = await getBiometricDisplayNameKey();
|
||||
// Translate the key
|
||||
const displayName = t(displayNameKey);
|
||||
setBiometricDisplayName(displayName);
|
||||
|
||||
const methods = await getEnabledAuthMethods();
|
||||
@@ -60,7 +62,7 @@ export default function VaultUnlockSettingsScreen() : React.ReactNode {
|
||||
};
|
||||
|
||||
initializeAuth();
|
||||
}, [getEnabledAuthMethods, getBiometricDisplayName, t]);
|
||||
}, [getEnabledAuthMethods, getBiometricDisplayNameKey, t]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!initialized) {
|
||||
|
||||
@@ -85,8 +85,9 @@ export default function LoginScreen() : React.ReactNode {
|
||||
passwordHashBase64: string,
|
||||
initiateLoginResponse: LoginResponse
|
||||
) : Promise<void> => {
|
||||
// Get biometric display name
|
||||
const biometricDisplayName = await authContext.getBiometricDisplayName();
|
||||
// Get biometric display name key and translate it
|
||||
const biometricDisplayNameKey = await authContext.getBiometricDisplayNameKey();
|
||||
const biometricDisplayName = t(biometricDisplayNameKey);
|
||||
const isBiometricsEnabledOnDevice = await authContext.isBiometricsEnabledOnDevice();
|
||||
|
||||
if (isBiometricsEnabledOnDevice) {
|
||||
|
||||
@@ -31,7 +31,7 @@ export default function UnlockScreen() : React.ReactNode {
|
||||
const colors = useColors();
|
||||
const { t } = useTranslation();
|
||||
const webApi = useWebApi();
|
||||
const { getBiometricDisplayName } = useAuth();
|
||||
const { getBiometricDisplayNameKey } = useAuth();
|
||||
const [biometricDisplayName, setBiometricDisplayName] = useState('');
|
||||
|
||||
/**
|
||||
@@ -58,12 +58,12 @@ export default function UnlockScreen() : React.ReactNode {
|
||||
const enabled = await isBiometricsEnabled();
|
||||
setIsBiometricsAvailable(enabled);
|
||||
|
||||
const displayName = await getBiometricDisplayName();
|
||||
setBiometricDisplayName(displayName);
|
||||
const displayNameKey = await getBiometricDisplayNameKey();
|
||||
setBiometricDisplayName(t(displayNameKey));
|
||||
};
|
||||
fetchBiometricConfig();
|
||||
|
||||
}, [isBiometricsEnabled, getKeyDerivationParams, getBiometricDisplayName]);
|
||||
}, [isBiometricsEnabled, getKeyDerivationParams, getBiometricDisplayNameKey, t]);
|
||||
|
||||
/**
|
||||
* Handle the unlock.
|
||||
|
||||
@@ -3,7 +3,6 @@ import { NavigationContainerRef, ParamListBase } from '@react-navigation/native'
|
||||
import * as LocalAuthentication from 'expo-local-authentication';
|
||||
import { router, useGlobalSearchParams, usePathname } from 'expo-router';
|
||||
import React, { createContext, useContext, useState, useEffect, useMemo, useCallback, useRef } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { AppState, Platform } from 'react-native';
|
||||
|
||||
import EncryptionUtility from '@/utils/EncryptionUtility';
|
||||
@@ -30,10 +29,10 @@ type AuthContextType = {
|
||||
globalMessage: string | null;
|
||||
clearGlobalMessage: () => void;
|
||||
setAuthMethods: (methods: AuthMethod[]) => Promise<void>;
|
||||
getAuthMethodDisplay: () => Promise<string>;
|
||||
getAuthMethodDisplayKey: () => Promise<string>;
|
||||
getAutoLockTimeout: () => Promise<number>;
|
||||
setAutoLockTimeout: (timeout: number) => Promise<void>;
|
||||
getBiometricDisplayName: () => Promise<string>;
|
||||
getBiometricDisplayNameKey: () => Promise<string>;
|
||||
isBiometricsEnabledOnDevice: () => Promise<boolean>;
|
||||
setOfflineMode: (isOffline: boolean) => void;
|
||||
verifyPassword: (password: string) => Promise<string | null>;
|
||||
@@ -56,7 +55,6 @@ const AuthContext = createContext<AuthContextType | undefined>(undefined);
|
||||
* AuthProvider to provide the authentication state to the app that components can use.
|
||||
*/
|
||||
export const AuthProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => {
|
||||
const { t } = useTranslation();
|
||||
const [isLoggedIn, setIsLoggedIn] = useState(false);
|
||||
const [isInitialized, setIsInitialized] = useState(false);
|
||||
const [username, setUsername] = useState<string | null>(null);
|
||||
@@ -70,6 +68,7 @@ export const AuthProvider: React.FC<{ children: React.ReactNode }> = ({ children
|
||||
const params = useGlobalSearchParams();
|
||||
const lastRouteRef = useRef<{ path: string, params?: object }>({ path: pathname, params });
|
||||
|
||||
|
||||
useEffect(() => {
|
||||
lastRouteRef.current = { path: pathname, params };
|
||||
}, [pathname, params]);
|
||||
@@ -201,21 +200,21 @@ export const AuthProvider: React.FC<{ children: React.ReactNode }> = ({ children
|
||||
}, []);
|
||||
|
||||
/**
|
||||
* Get the appropriate biometric display name based on device capabilities
|
||||
* Get the appropriate biometric display name translation key based on device capabilities
|
||||
*/
|
||||
const getBiometricDisplayName = useCallback(async (): Promise<string> => {
|
||||
const getBiometricDisplayNameKey = useCallback(async (): Promise<string> => {
|
||||
try {
|
||||
const hasBiometrics = await LocalAuthentication.hasHardwareAsync();
|
||||
const enrolled = await LocalAuthentication.isEnrolledAsync();
|
||||
|
||||
// For Android, we use the term "Biometrics" for facial recognition and fingerprint.
|
||||
if (Platform.OS === 'android') {
|
||||
return t('settings.vaultUnlockSettings.biometrics');
|
||||
return 'settings.vaultUnlockSettings.biometrics';
|
||||
}
|
||||
|
||||
// For iOS, we check if the device has explicit Face ID or Touch ID support.
|
||||
if (!hasBiometrics || !enrolled) {
|
||||
return t('settings.vaultUnlockSettings.faceIdTouchId');
|
||||
return 'settings.vaultUnlockSettings.faceIdTouchId';
|
||||
}
|
||||
|
||||
const types = await LocalAuthentication.supportedAuthenticationTypesAsync();
|
||||
@@ -223,35 +222,35 @@ export const AuthProvider: React.FC<{ children: React.ReactNode }> = ({ children
|
||||
const hasTouchIDSupport = types.includes(LocalAuthentication.AuthenticationType.FINGERPRINT);
|
||||
|
||||
if (hasFaceIDSupport) {
|
||||
return t('settings.vaultUnlockSettings.faceId');
|
||||
return 'settings.vaultUnlockSettings.faceId';
|
||||
} else if (hasTouchIDSupport) {
|
||||
return t('settings.vaultUnlockSettings.touchId');
|
||||
return 'settings.vaultUnlockSettings.touchId';
|
||||
}
|
||||
|
||||
return t('settings.vaultUnlockSettings.faceIdTouchId');
|
||||
return 'settings.vaultUnlockSettings.faceIdTouchId';
|
||||
} catch (error) {
|
||||
console.error('Failed to get biometric display name:', error);
|
||||
return t('settings.vaultUnlockSettings.faceIdTouchId');
|
||||
return 'settings.vaultUnlockSettings.faceIdTouchId';
|
||||
}
|
||||
}, [t]);
|
||||
}, []);
|
||||
|
||||
/**
|
||||
* Get the display label for the current auth method
|
||||
* Get the display label translation key for the current auth method
|
||||
* Prefers Face ID if enabled, otherwise falls back to Password
|
||||
*/
|
||||
const getAuthMethodDisplay = useCallback(async (): Promise<string> => {
|
||||
const getAuthMethodDisplayKey = useCallback(async (): Promise<string> => {
|
||||
const methods = await getEnabledAuthMethods();
|
||||
if (methods.includes('faceid')) {
|
||||
try {
|
||||
if (await isBiometricsEnabledOnDevice()) {
|
||||
return await getBiometricDisplayName();
|
||||
return await getBiometricDisplayNameKey();
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Failed to check Face ID enrollment:', error);
|
||||
}
|
||||
}
|
||||
return t('credentials.password');
|
||||
}, [getEnabledAuthMethods, getBiometricDisplayName, isBiometricsEnabledOnDevice, t]);
|
||||
return 'credentials.password';
|
||||
}, [getEnabledAuthMethods, getBiometricDisplayNameKey, isBiometricsEnabledOnDevice]);
|
||||
|
||||
/**
|
||||
* Get the auto-lock timeout from the iOS credentials manager
|
||||
@@ -397,11 +396,11 @@ export const AuthProvider: React.FC<{ children: React.ReactNode }> = ({ children
|
||||
logout,
|
||||
clearGlobalMessage,
|
||||
setAuthMethods,
|
||||
getAuthMethodDisplay,
|
||||
getAuthMethodDisplayKey,
|
||||
isBiometricsEnabledOnDevice,
|
||||
getAutoLockTimeout,
|
||||
setAutoLockTimeout,
|
||||
getBiometricDisplayName,
|
||||
getBiometricDisplayNameKey,
|
||||
markAutofillConfigured,
|
||||
setReturnUrl,
|
||||
verifyPassword,
|
||||
@@ -422,11 +421,11 @@ export const AuthProvider: React.FC<{ children: React.ReactNode }> = ({ children
|
||||
logout,
|
||||
clearGlobalMessage,
|
||||
setAuthMethods,
|
||||
getAuthMethodDisplay,
|
||||
getAuthMethodDisplayKey,
|
||||
isBiometricsEnabledOnDevice,
|
||||
getAutoLockTimeout,
|
||||
setAutoLockTimeout,
|
||||
getBiometricDisplayName,
|
||||
getBiometricDisplayNameKey,
|
||||
markAutofillConfigured,
|
||||
setReturnUrl,
|
||||
verifyPassword,
|
||||
|
||||
Reference in New Issue
Block a user