Skip to content

Conversation

@Mishael-2584
Copy link
Contributor

@Mishael-2584 Mishael-2584 commented Jan 13, 2026

Description

Implements automatic re-authentication when 401 Unauthorized errors occur during sync operations (both data sync and app bundle updates), improving UX by preventing manual re-login.

Problem:
When users return to Formulus and attempt to sync after their auth token has expired, they encounter a 401 error and must manually navigate to Settings to re-login before syncing again.

Solution:

  • Automatically detects 401 Unauthorized errors during sync operations
  • Attempts to re-login using stored credentials from Keychain
  • Retries the failed operation once after successful auto-login
  • Prevents infinite retry loops (max 1 retry per operation)

Type of Change

  • Bug Fix
  • New Feature / Enhancement
  • Refactor / Code Cleanup
  • Documentation Update
  • Maintenance / Chore
  • Other (please specify):

Component(s) Affected

  • formulus (React Native mobile app)
  • formulus-formplayer (React web app)
  • synkronus (Go backend server)
  • synkronus-cli (Command-line utility)
  • Documentation
  • DevOps / CI/CD
  • Other:

Related Issue(s)

** Closes #143


Changes Made

Core Implementation

  1. src/api/synkronus/Auth.ts

    • Added autoLogin() function to re-authenticate using stored credentials
    • Added isUnauthorizedError() function to detect various 401 error formats
  2. src/api/synkronus/index.ts

    • Updated clearTokenCache() to also clear API instance and config
    • Ensures fresh API instance is created with new token after auto-login
  3. src/services/SyncService.ts

    • Added withAutoLoginRetry() wrapper method for automatic retry logic
    • Applied to: syncObservations(), updateAppBundle(), checkForUpdates()
    • Made notification service non-blocking to prevent sync hanging
  4. src/screens/SettingsScreen.tsx

    • Ensures server URL is saved before login (required by getApi())
    • Fixed for both manual login and QR code login paths
  5. src/screens/SyncScreen.tsx

    • Added timeout protection (30 minutes) to prevent infinite hanging
    • Enhanced error handling for update functions
    • Guaranteed finishSync() is always called in finally block

Test Coverage

  1. src/api/synkronus/__tests__/Auth.test.ts (15 tests)

    • Unit tests for isUnauthorizedError() and autoLogin()
    • Covers various 401 error formats and auto-login scenarios
  2. src/services/__tests__/SyncService.autoLogin.test.ts (8 tests)

    • Integration tests for auto-login retry logic in sync operations
    • Covers success, failure, and edge cases

Bug Fixes Included

  • Sync Hanging Issue: Fixed issue where sync would hang indefinitely after auto-login:
    • Made notification service non-blocking (fire-and-forget pattern)
    • Added 30-minute timeout protection
    • Enhanced error handling for update functions
    • Guaranteed UI state update in finally block

Testing

  • Unit tests added/updated
  • Integration tests added/updated
  • Manually tested
  • Tested on multiple platforms (if applicable)
  • Not applicable

Test Results

  • ✅ All 23 tests passing
  • Run: npm test -- Auth.test.ts SyncService.autoLogin.test.ts

Breaking Changes

  • This PR introduces breaking changes
  • This PR does NOT introduce breaking changes

If breaking changes, please describe migration steps:

N/A - This is a backward-compatible enhancement.


Edge Cases Handled

  • ✅ Missing credentials → Shows appropriate error message
  • ✅ Invalid credentials → Shows error, doesn't retry
  • ✅ Network errors → Passes through without retry
  • ✅ Notification service failures → Doesn't block sync
  • ✅ Infinite retry prevention → Max 1 retry per operation
  • ✅ Timeout protection → 30-minute max sync time

Documentation Updates

  • Documentation has been updated
  • Documentation update is not required

Checklist

  • Code follows project style guidelines
  • All existing tests pass
  • New tests added for new functionality
  • PR title follows Conventional Commits format
  • Prettier formatting applied
  • No linter errors
  • Comprehensive error handling
  • Detailed logging for debugging

Mishael-2584 and others added 3 commits January 13, 2026 15:15
Implements automatic re-authentication when 401 Unauthorized errors occur during sync operations (both data sync and app bundle updates).

- Added autoLogin() and isUnauthorizedError() functions in Auth.ts

- Updated clearTokenCache() to clear API instance after auto-login

- Added withAutoLoginRetry() wrapper in SyncService

- Fixed sync hanging issue (non-blocking notifications, timeout protection)

- Added comprehensive test coverage (23 tests)

- Fixed server URL saving before login in SettingsScreen
- Remove unused mockUserInfo variable in Auth.test.ts

- Remove unnecessary undefined initialization in SyncScreen.tsx

- Remove unnecessary undefined initialization in FormplayerModal.tsx
Copy link
Contributor

@r0ssing r0ssing left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks great - thanks @Mishael-2584 ! 🚀
Let's pull a fresh Formulus release once this is merged

@Mishael-2584 Mishael-2584 merged commit d71ef51 into dev Jan 13, 2026
8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Formulus] Auto-login after auth. token timeouts

3 participants