mirror of
https://github.com/aliasvault/aliasvault.git
synced 2026-05-24 16:32:20 -04:00
Tweak offline mode detection (#1404)
This commit is contained in:
@@ -9,6 +9,7 @@ import { useWebApi } from '@/entrypoints/popup/context/WebApiContext';
|
||||
import type { EncryptionKeyDerivationParams } from '@/utils/dist/core/models/metadata';
|
||||
import type { VaultResponse } from '@/utils/dist/core/models/webapi';
|
||||
import { EncryptionUtility } from '@/utils/EncryptionUtility';
|
||||
import { ApiAuthError } from '@/utils/types/errors/ApiAuthError';
|
||||
import { NetworkError } from '@/utils/types/errors/NetworkError';
|
||||
import { VaultVersionIncompatibleError } from '@/utils/types/errors/VaultVersionIncompatibleError';
|
||||
import type { VaultUploadResponse } from '@/utils/types/messaging/VaultUploadResponse';
|
||||
@@ -303,6 +304,11 @@ export const useVaultSync = (): { syncVault: (options?: VaultSyncOptions) => Pro
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check if it's an auth error (session expired) - logout is already triggered by WebApiService
|
||||
if (err instanceof ApiAuthError) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check if it's a network error - enter offline mode if we have a local vault
|
||||
if (err instanceof NetworkError) {
|
||||
if (dbContext.dbAvailable) {
|
||||
|
||||
@@ -81,24 +81,34 @@ const Unlock: React.FC = () => {
|
||||
* Returns { online: boolean, error: string | null }
|
||||
*/
|
||||
const checkStatus = async () : Promise<{ online: boolean; error: string | null }> => {
|
||||
const statusResponse = await webApi.getStatus();
|
||||
try {
|
||||
const statusResponse = await webApi.getStatus();
|
||||
|
||||
// Server is offline (network error) - this is OK for unlock, we can use local vault
|
||||
if (statusResponse.serverVersion === '0.0.0') {
|
||||
setIsInitialLoading(false);
|
||||
await dbContext.setIsOffline(true);
|
||||
return { online: false, error: null };
|
||||
}
|
||||
|
||||
const statusError = webApi.validateStatusResponse(statusResponse);
|
||||
if (statusError !== null) {
|
||||
await app.logout(t('common.errors.' + statusError));
|
||||
return { online: false, error: statusError };
|
||||
}
|
||||
|
||||
// Server is offline - this is OK for unlock, we can use local vault
|
||||
if (statusResponse.serverVersion === '0.0.0') {
|
||||
setIsInitialLoading(false);
|
||||
await dbContext.setIsOffline(true);
|
||||
return { online: false, error: null };
|
||||
await dbContext.setIsOffline(false);
|
||||
return { online: true, error: null };
|
||||
} catch {
|
||||
/**
|
||||
* Non-network errors (e.g., session expired, auth failures) are thrown by getStatus().
|
||||
* The logout event is already emitted by the WebApiService, so we just return an error
|
||||
* and don't set offline mode since the server is reachable.
|
||||
*/
|
||||
setIsInitialLoading(false);
|
||||
return { online: false, error: 'sessionExpired' };
|
||||
}
|
||||
|
||||
const statusError = webApi.validateStatusResponse(statusResponse);
|
||||
if (statusError !== null) {
|
||||
await app.logout(t('common.errors.' + statusError));
|
||||
return { online: false, error: statusError };
|
||||
}
|
||||
|
||||
setIsInitialLoading(false);
|
||||
await dbContext.setIsOffline(false);
|
||||
return { online: true, error: null };
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -3,6 +3,7 @@ import type { StatusResponse } from '@/utils/dist/core/models/webapi';
|
||||
import { logoutEventEmitter } from '@/events/LogoutEventEmitter';
|
||||
|
||||
import { AppInfo } from "./AppInfo";
|
||||
import { ApiAuthError } from './types/errors/ApiAuthError';
|
||||
import { NetworkError } from './types/errors/NetworkError';
|
||||
|
||||
import { storage } from '#imports';
|
||||
@@ -72,13 +73,13 @@ export class WebApiService {
|
||||
});
|
||||
|
||||
if (!retryResponse.ok) {
|
||||
throw new Error('Request failed after token refresh');
|
||||
throw new ApiAuthError('Request failed after token refresh');
|
||||
}
|
||||
|
||||
return parseJson ? retryResponse.json() : retryResponse as unknown as T;
|
||||
} else {
|
||||
logoutEventEmitter.emit('auth.errors.sessionExpired');
|
||||
throw new Error('Session expired');
|
||||
throw new ApiAuthError('Session expired');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -211,15 +212,21 @@ export class WebApiService {
|
||||
|
||||
/**
|
||||
* Calls the status endpoint to check if the auth tokens are still valid, app is supported and the vault is up to date.
|
||||
* Returns offline indicator (serverVersion: '0.0.0') for network failures and server errors (5xx, 404, etc.).
|
||||
* Auth errors (ApiAuthError) are re-thrown to be handled appropriately (e.g., trigger logout).
|
||||
*/
|
||||
public async getStatus(): Promise<StatusResponse> {
|
||||
try {
|
||||
return await this.get<StatusResponse>('Auth/status');
|
||||
} catch {
|
||||
} catch (error) {
|
||||
/**
|
||||
* If the status endpoint is not available, return a default status response which will trigger
|
||||
* a logout and error message.
|
||||
* Only re-throw ApiAuthError (session expired, auth failures).
|
||||
* All other errors (NetworkError, HTTP 5xx, 404, etc.) indicate the server
|
||||
* is unreachable or misconfigured, so return offline indicator.
|
||||
*/
|
||||
if (error instanceof ApiAuthError) {
|
||||
throw error;
|
||||
}
|
||||
return {
|
||||
clientVersionSupported: true,
|
||||
serverVersion: '0.0.0',
|
||||
|
||||
Reference in New Issue
Block a user