mirror of
https://github.com/aliasvault/aliasvault.git
synced 2026-05-18 21:40:41 -04:00
Cleanup RN AsyncStorage calls (#520)
This commit is contained in:
@@ -47,17 +47,8 @@ export default function SettingsScreen() : React.ReactNode {
|
||||
*/
|
||||
const loadStoredSettings = useCallback(async () : Promise<void> => {
|
||||
try {
|
||||
// Try to get API URL from native layer first, fallback to AsyncStorage
|
||||
let apiUrl: string | null = null;
|
||||
try {
|
||||
apiUrl = await NativeVaultManager.getApiUrl();
|
||||
} catch (nativeError) {
|
||||
console.warn('Failed to get API URL from native layer, falling back to AsyncStorage:', nativeError);
|
||||
apiUrl = await AsyncStorage.getItem('apiUrl');
|
||||
}
|
||||
|
||||
const apiUrl = await NativeVaultManager.getApiUrl();
|
||||
const matchingOption = DEFAULT_OPTIONS.find(opt => opt.value === apiUrl);
|
||||
|
||||
if (matchingOption) {
|
||||
setSelectedOption(matchingOption.value);
|
||||
} else if (apiUrl) {
|
||||
@@ -81,8 +72,6 @@ export default function SettingsScreen() : React.ReactNode {
|
||||
const handleOptionChange = async (value: string) : Promise<void> => {
|
||||
setSelectedOption(value);
|
||||
if (value !== 'custom') {
|
||||
// Sync to both AsyncStorage and native layer
|
||||
await AsyncStorage.setItem('apiUrl', value);
|
||||
try {
|
||||
await NativeVaultManager.setApiUrl(value);
|
||||
} catch (error) {
|
||||
|
||||
@@ -126,22 +126,10 @@ export const AuthProvider: React.FC<{ children: React.ReactNode }> = ({ children
|
||||
* Set auth tokens in storage as part of the login process. After db is initialized, the login method should be called as well.
|
||||
*/
|
||||
const setAuthTokens = useCallback(async (username: string, accessToken: string, refreshToken: string): Promise<void> => {
|
||||
// Store username in native layer (new approach)
|
||||
await NativeVaultManager.setUsername(username);
|
||||
await NativeVaultManager.setAuthTokens(accessToken, refreshToken);
|
||||
|
||||
// Keep AsyncStorage for backward compatibility / migration
|
||||
// TODO: Remove AsyncStorage username storage in future version
|
||||
await AsyncStorage.setItem('username', username);
|
||||
await AsyncStorage.setItem('accessToken', accessToken);
|
||||
await AsyncStorage.setItem('refreshToken', refreshToken);
|
||||
|
||||
// Sync tokens to native layer
|
||||
try {
|
||||
await NativeVaultManager.setAuthTokens(accessToken, refreshToken);
|
||||
} catch (error) {
|
||||
console.error('Failed to sync auth tokens to native layer:', error);
|
||||
}
|
||||
|
||||
// Update React state
|
||||
setUsername(username);
|
||||
}, []);
|
||||
|
||||
@@ -150,38 +138,51 @@ export const AuthProvider: React.FC<{ children: React.ReactNode }> = ({ children
|
||||
* @returns object containing whether the user is logged in and enabled auth methods
|
||||
*/
|
||||
const initializeAuth = useCallback(async (): Promise<{ isLoggedIn: boolean; enabledAuthMethods: AuthMethod[] }> => {
|
||||
const accessToken = await AsyncStorage.getItem('accessToken') as string;
|
||||
const refreshToken = await AsyncStorage.getItem('refreshToken') as string;
|
||||
// Sync legacy config to native layer (can be removed in future version 0.25.0+)
|
||||
syncLegacyConfigToNative();
|
||||
|
||||
// Try to get username from native layer first (new approach)
|
||||
let username = await NativeVaultManager.getUsername();
|
||||
|
||||
// Fallback to AsyncStorage for migration
|
||||
if (!username) {
|
||||
username = await AsyncStorage.getItem('username');
|
||||
// Migrate to native storage
|
||||
if (username) {
|
||||
await NativeVaultManager.setUsername(username);
|
||||
}
|
||||
}
|
||||
|
||||
// Load offline mode from native layer
|
||||
const offline = await NativeVaultManager.getOfflineMode();
|
||||
setIsOffline(offline);
|
||||
const accessToken = await NativeVaultManager.getAccessToken();
|
||||
const username = await NativeVaultManager.getUsername();
|
||||
|
||||
// Update local React state
|
||||
let isAuthenticated = false;
|
||||
let methods: AuthMethod[] = ['password'];
|
||||
|
||||
if (accessToken && refreshToken && username) {
|
||||
// Check if user is logged in (has both access token and username)
|
||||
if (accessToken && username) {
|
||||
setUsername(username);
|
||||
setIsLoggedIn(true);
|
||||
isAuthenticated = true;
|
||||
methods = await getEnabledAuthMethods();
|
||||
}
|
||||
|
||||
const offline = await NativeVaultManager.getOfflineMode();
|
||||
|
||||
setIsInitialized(true);
|
||||
setIsOffline(offline);
|
||||
return { isLoggedIn: isAuthenticated, enabledAuthMethods: methods };
|
||||
}, [getEnabledAuthMethods]);
|
||||
|
||||
/**
|
||||
* Sync legacy config to native layer
|
||||
*/
|
||||
const syncLegacyConfigToNative = useCallback(async (): Promise<void> => {
|
||||
// Migrate tokens from AsyncStorage to native on first launch, then remove to prevent repeated syncs
|
||||
const accessToken = await AsyncStorage.getItem('accessToken');
|
||||
const refreshToken = await AsyncStorage.getItem('refreshToken');
|
||||
|
||||
if (accessToken && refreshToken) {
|
||||
await NativeVaultManager.setAuthTokens(accessToken, refreshToken);
|
||||
await AsyncStorage.multiRemove(['accessToken', 'refreshToken']);
|
||||
}
|
||||
|
||||
const username = await AsyncStorage.getItem('username');
|
||||
if (username) {
|
||||
await NativeVaultManager.setUsername(username);
|
||||
await AsyncStorage.removeItem('username');
|
||||
}
|
||||
}, []);
|
||||
|
||||
/**
|
||||
* Set logged in status to true which refreshes the app.
|
||||
*/
|
||||
@@ -199,7 +200,7 @@ export const AuthProvider: React.FC<{ children: React.ReactNode }> = ({ children
|
||||
await NativeVaultManager.clearAuthTokens();
|
||||
|
||||
// Clear from AsyncStorage (for backward compatibility)
|
||||
// TODO: Remove AsyncStorage cleanup in future version
|
||||
// TODO: Remove AsyncStorage cleanup in future version 0.25.0+
|
||||
await AsyncStorage.removeItem('username');
|
||||
await AsyncStorage.removeItem('accessToken');
|
||||
await AsyncStorage.removeItem('refreshToken');
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import AsyncStorage from '@react-native-async-storage/async-storage';
|
||||
import { useState } from 'react';
|
||||
|
||||
import { AppInfo } from '@/utils/AppInfo';
|
||||
@@ -21,7 +20,6 @@ export const useApiUrl = (): {
|
||||
*/
|
||||
const loadApiUrl = async (): Promise<void> => {
|
||||
try {
|
||||
// Try to get from native layer first
|
||||
const storedUrl = await NativeVaultManager.getApiUrl();
|
||||
if (storedUrl && storedUrl.length > 0) {
|
||||
setApiUrl(storedUrl);
|
||||
@@ -29,14 +27,7 @@ export const useApiUrl = (): {
|
||||
setApiUrl(AppInfo.DEFAULT_API_URL);
|
||||
}
|
||||
} catch (error) {
|
||||
console.warn('Failed to get API URL from native layer, falling back to AsyncStorage:', error);
|
||||
// Fallback to AsyncStorage
|
||||
const storedUrl = await AsyncStorage.getItem('apiUrl');
|
||||
if (storedUrl && storedUrl.length > 0) {
|
||||
setApiUrl(storedUrl);
|
||||
} else {
|
||||
setApiUrl(AppInfo.DEFAULT_API_URL);
|
||||
}
|
||||
console.warn('Failed to get API URL from native layer:', error);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
import AsyncStorage from '@react-native-async-storage/async-storage';
|
||||
|
||||
import { AppInfo } from '@/utils/AppInfo';
|
||||
import type { StatusResponse, VaultResponse, AuthLogModel, RefreshToken } from '@/utils/dist/shared/models/webapi';
|
||||
|
||||
@@ -25,14 +23,6 @@ type NativeWebApiResponse = {
|
||||
* This class now acts as a proxy to the native layer, where all WebAPI calls are executed.
|
||||
*/
|
||||
export class WebApiService {
|
||||
/**
|
||||
* Constructor for the WebApiService class.
|
||||
*/
|
||||
public constructor() {
|
||||
// Initialize API URL and tokens from AsyncStorage if they exist
|
||||
this.syncLegacyConfigToNative();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the base URL for the API from settings.
|
||||
*/
|
||||
@@ -352,44 +342,7 @@ export class WebApiService {
|
||||
return apiUrl || AppInfo.DEFAULT_API_URL;
|
||||
} catch (error) {
|
||||
console.error('Failed to get API URL from native layer:', error);
|
||||
// Fallback to AsyncStorage
|
||||
const result = await AsyncStorage.getItem('apiUrl') as string;
|
||||
if (result && result.length > 0) {
|
||||
return result;
|
||||
}
|
||||
return AppInfo.DEFAULT_API_URL;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sync configuration from AsyncStorage to native layer on initialization.
|
||||
*
|
||||
* This is primarily for backward compatibility / migration purposes:
|
||||
* - Existing users who upgraded from a version without native WebAPI will have tokens in AsyncStorage
|
||||
* - This ensures those tokens are migrated to the native layer on first launch after upgrade
|
||||
* - For new installations, all tokens/config go directly to native layer, so this becomes a no-op
|
||||
*
|
||||
* TODO: This can be removed in a future version (e.g., after some time that 0.24.0 is released)
|
||||
* and once most if not all active users have migrated.
|
||||
*/
|
||||
private async syncLegacyConfigToNative(): Promise<void> {
|
||||
try {
|
||||
// Migrate API URL from AsyncStorage to native on first launch, then remove to prevent repeated syncs
|
||||
const apiUrl = await AsyncStorage.getItem('apiUrl');
|
||||
if (apiUrl) {
|
||||
await NativeVaultManager.setApiUrl(apiUrl);
|
||||
await AsyncStorage.removeItem('apiUrl');
|
||||
}
|
||||
|
||||
// Migrate tokens from AsyncStorage to native on first launch, then remove to prevent repeated syncs
|
||||
const accessToken = await AsyncStorage.getItem('accessToken');
|
||||
const refreshToken = await AsyncStorage.getItem('refreshToken');
|
||||
if (accessToken && refreshToken) {
|
||||
await NativeVaultManager.setAuthTokens(accessToken, refreshToken);
|
||||
await AsyncStorage.multiRemove(['accessToken', 'refreshToken']);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Failed to sync config to native layer:', error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user