Skip to content

feat: enforce hard session expiry on foreground and in request interceptor#728

Merged
RUKAYAT-CODER merged 1 commit into
rinafcode:mainfrom
No-bodyq:security/session-expiry-enforcement
Jun 28, 2026
Merged

feat: enforce hard session expiry on foreground and in request interceptor#728
RUKAYAT-CODER merged 1 commit into
rinafcode:mainfrom
No-bodyq:security/session-expiry-enforcement

Conversation

@No-bodyq

Copy link
Copy Markdown
Contributor

Summary

  • Added checkSessionValidity() to src/services/secureStorage.ts — reads sessionExpiresAt from SecureStore (Keychain/Keystore) and returns { valid, expiringSoon, msUntilExpiry }; the 5-minute window is encapsulated there so callers don't duplicate the constant
  • Refactored checkSessionOnForeground in App.tsx to call checkSessionValidity() instead of reading sessionExpiresAt directly from the Zustand store; SecureStore is the authoritative source on foreground transition
  • Removed the disruptive "Session expiring soon" alert — setSessionExpiringSoon(true) is set so the UI can react, but the proactive refresh is silent
  • Added a session expiry guard to the apiClient request interceptor in src/services/api/axios.config.ts; any authenticated request made while Date.now() >= sessionExpiresAt is rejected immediately with SESSION_EXPIRED and triggers logout — the backend never sees an expired token
  • Unit tests cover: no stored expiry, already expired, expiring within 5 minutes, > 5 minutes remaining, and the exact boundary at 5 minutes

Type of Change

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • Chore / Refactor (no functional changes)

Testing Done

  • Unit Tests
  • Integration Tests
  • Manual Verification (e.g., iOS/Android UI checks)

Security Considerations

  • Does this store user data securely (e.g., avoiding plain AsyncStorage for sensitive data)? — Session expiry read from SecureStore (Keychain/Keystore); no change to storage backend
  • Is token handling secure (no token exposure in logs or UI)? — Expired-token requests are blocked before the token is even read from storage; logout clears tokens from both store and SecureStore
  • Are all user inputs validated? — N/A to this change
  • Is deep link handling safe from malicious payloads? — N/A to this change

Performance Considerations

  • Are React hooks (useCallback, useMemo) used appropriately to prevent unnecessary renders? — checkSessionOnForeground runs only on mount and background→active transitions, same as before
  • Is FlatList optimized (e.g., using getItemLayout, keyExtractor)? — N/A
  • Are asynchronous patterns handled correctly (e.g., useEffect cleanup to avoid memory leaks)? — AppState subscription is removed in cleanup; no new subscriptions added
  • Have bundle size impacts been considered? — No new dependencies; checkSessionValidity is a small addition to an existing module

Checklist

  • I have read the CONTRIBUTING guide.
  • My code follows the style guidelines of this project.
  • I have updated the documentation accordingly. — N/A; no public API surface changed
  • Are there architectural changes? If so, is there an Architectural Decision Record (ADR)? — No architectural changes; SecureStore remains the source of truth

Closes #580

@drips-wave

drips-wave Bot commented Jun 28, 2026

Copy link
Copy Markdown

@No-bodyq Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits.

You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀

Learn more about application limits

@RUKAYAT-CODER

Copy link
Copy Markdown
Contributor

Thank you for contributing to the project.

@RUKAYAT-CODER RUKAYAT-CODER merged commit 1003b78 into rinafcode:main Jun 28, 2026
2 of 14 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.

[Security] Access token not force-expired when session expiresAt passes — user stays authenticated

2 participants