mirror of
https://github.com/aliasvault/aliasvault.git
synced 2026-03-09 10:19:03 -04:00
Add mobile app login flow abort when manually skipped flow (#520)
This commit is contained in:
@@ -24,6 +24,7 @@ export default function Initialize() : React.ReactNode {
|
||||
const skipButtonTimeoutRef = useRef<NodeJS.Timeout | null>(null);
|
||||
const lastStatusRef = useRef<string>('');
|
||||
const canShowSkipButtonRef = useRef(false); // Only allow skip button after vault unlock
|
||||
const abortControllerRef = useRef<AbortController | null>(null);
|
||||
const { t } = useTranslation();
|
||||
const app = useApp();
|
||||
const { syncVault } = useVaultSync();
|
||||
@@ -68,6 +69,13 @@ export default function Initialize() : React.ReactNode {
|
||||
* Handle offline scenario - show alert with options to open local vault or retry sync.
|
||||
*/
|
||||
const handleOfflineFlow = useCallback((): void => {
|
||||
// Don't show the alert if we're already in offline mode
|
||||
if (app.isOffline) {
|
||||
console.debug('Already in offline mode, skipping offline flow alert');
|
||||
router.replace('/(tabs)/credentials');
|
||||
return;
|
||||
}
|
||||
|
||||
Alert.alert(
|
||||
t('app.alerts.syncIssue'),
|
||||
t('app.alerts.syncIssueMessage'),
|
||||
@@ -136,6 +144,12 @@ export default function Initialize() : React.ReactNode {
|
||||
updateStatus(t('app.status.retryingConnection'));
|
||||
setShowSkipButton(false);
|
||||
|
||||
// Abort any pending sync operation
|
||||
if (abortControllerRef.current) {
|
||||
abortControllerRef.current.abort();
|
||||
abortControllerRef.current = null;
|
||||
}
|
||||
|
||||
// Clear any existing timeout
|
||||
if (skipButtonTimeoutRef.current) {
|
||||
clearTimeout(skipButtonTimeoutRef.current);
|
||||
@@ -241,9 +255,13 @@ export default function Initialize() : React.ReactNode {
|
||||
canShowSkipButtonRef.current = true;
|
||||
}
|
||||
|
||||
// Create abort controller for sync operations
|
||||
abortControllerRef.current = new AbortController();
|
||||
|
||||
// Now perform vault sync (network operations - these are skippable)
|
||||
await syncVault({
|
||||
initialSync: true,
|
||||
abortSignal: abortControllerRef.current.signal,
|
||||
/**
|
||||
* Handle the status update.
|
||||
*/
|
||||
@@ -301,6 +319,13 @@ export default function Initialize() : React.ReactNode {
|
||||
* Handle skip button press by calling the offline handler.
|
||||
*/
|
||||
const handleSkipPress = (): void => {
|
||||
// Abort any pending sync operation
|
||||
if (abortControllerRef.current) {
|
||||
console.debug('Aborting pending sync operation');
|
||||
abortControllerRef.current.abort();
|
||||
abortControllerRef.current = null;
|
||||
}
|
||||
|
||||
// Clear any existing timeout
|
||||
if (skipButtonTimeoutRef.current) {
|
||||
clearTimeout(skipButtonTimeoutRef.current);
|
||||
|
||||
@@ -44,6 +44,7 @@ type VaultSyncOptions = {
|
||||
onStatus?: (message: string) => void;
|
||||
onOffline?: () => void;
|
||||
onUpgradeRequired?: () => void;
|
||||
abortSignal?: AbortSignal;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -58,12 +59,18 @@ export const useVaultSync = () : {
|
||||
const dbContext = useDb();
|
||||
|
||||
const syncVault = useCallback(async (options: VaultSyncOptions = {}) => {
|
||||
const { initialSync = false, onSuccess, onError, onStatus, onOffline, onUpgradeRequired } = options;
|
||||
const { initialSync = false, onSuccess, onError, onStatus, onOffline, onUpgradeRequired, abortSignal } = options;
|
||||
|
||||
// For the initial sync, we add an artifical delay to various steps which makes it feel more fluid.
|
||||
const enableDelay = initialSync;
|
||||
|
||||
try {
|
||||
// Check if operation was aborted
|
||||
if (abortSignal?.aborted) {
|
||||
console.debug('VaultSync: Operation aborted before starting');
|
||||
return false;
|
||||
}
|
||||
|
||||
const { isLoggedIn } = await app.initializeAuth();
|
||||
|
||||
if (!isLoggedIn) {
|
||||
@@ -71,6 +78,12 @@ export const useVaultSync = () : {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check if operation was aborted
|
||||
if (abortSignal?.aborted) {
|
||||
console.debug('VaultSync: Operation aborted after auth check');
|
||||
return false;
|
||||
}
|
||||
|
||||
// Update status
|
||||
onStatus?.(t('vault.checkingVaultUpdates'));
|
||||
|
||||
@@ -79,6 +92,12 @@ export const useVaultSync = () : {
|
||||
await new Promise(resolve => setTimeout(resolve, 300));
|
||||
}
|
||||
|
||||
// Check if operation was aborted
|
||||
if (abortSignal?.aborted) {
|
||||
console.debug('VaultSync: Operation aborted after status update');
|
||||
return false;
|
||||
}
|
||||
|
||||
// Step 1: Check if a new vault version is available
|
||||
// This calls Auth/status endpoint and compares vault revisions
|
||||
let hasNewVault = false;
|
||||
@@ -86,11 +105,24 @@ export const useVaultSync = () : {
|
||||
|
||||
try {
|
||||
const versionCheckResult = await NativeVaultManager.isNewVaultVersionAvailable();
|
||||
|
||||
// Check if operation was aborted after version check
|
||||
if (abortSignal?.aborted) {
|
||||
console.debug('VaultSync: Operation aborted after version check');
|
||||
return false;
|
||||
}
|
||||
|
||||
hasNewVault = versionCheckResult.isNewVersionAvailable;
|
||||
newRevision = versionCheckResult.newRevision;
|
||||
|
||||
// Step 2: If a new version is available, download it
|
||||
if (hasNewVault && newRevision != null) {
|
||||
// Check if operation was aborted before download
|
||||
if (abortSignal?.aborted) {
|
||||
console.debug('VaultSync: Operation aborted before download');
|
||||
return false;
|
||||
}
|
||||
|
||||
onStatus?.(t('vault.syncingUpdatedVault'));
|
||||
|
||||
// Run downloadVault with a min delay for UX purposes
|
||||
|
||||
Reference in New Issue
Block a user