diff --git a/app/(tabs)/index.tsx b/app/(tabs)/index.tsx index 44858e9..4f368da 100644 --- a/app/(tabs)/index.tsx +++ b/app/(tabs)/index.tsx @@ -10,6 +10,8 @@ import { AppColors, FontSizes, Spacing } from '@/constants/theme'; const DASHBOARD_URL = 'https://react.eluxnetworks.net/dashboard'; // URLs that indicate session expired (login page) const LOGIN_URL_PATTERNS = ['/login', '/auth', '/signin']; +// Text patterns that indicate session expired (shown in page content) +const SESSION_EXPIRED_PATTERNS = ['session expired', 'session has expired', 'token expired', 'please log in']; export default function HomeScreen() { const { user } = useAuth(); @@ -134,12 +136,13 @@ export default function HomeScreen() { } }, [isRefreshingToken]); - // JavaScript to inject auth token into localStorage + // JavaScript to inject auth token into localStorage and monitor for session expiry // Web app expects auth2 as JSON: {username, token, user_id} const injectedJavaScript = authToken ? ` (function() { try { + // Inject auth data var authData = { username: '${userName || ''}', token: '${authToken}', @@ -147,6 +150,33 @@ export default function HomeScreen() { }; localStorage.setItem('auth2', JSON.stringify(authData)); console.log('Auth injected:', authData.username); + + // Monitor page content for session expired messages + var sessionExpiredPatterns = ${JSON.stringify(SESSION_EXPIRED_PATTERNS)}; + + function checkForSessionExpired() { + var bodyText = (document.body?.innerText || '').toLowerCase(); + for (var i = 0; i < sessionExpiredPatterns.length; i++) { + if (bodyText.includes(sessionExpiredPatterns[i])) { + console.log('Session expired detected in page content'); + window.ReactNativeWebView?.postMessage(JSON.stringify({ type: 'SESSION_EXPIRED' })); + return true; + } + } + return false; + } + + // Check after page loads and periodically + setTimeout(checkForSessionExpired, 1000); + setTimeout(checkForSessionExpired, 3000); + + // Also observe DOM changes for dynamic content + var observer = new MutationObserver(function() { + checkForSessionExpired(); + }); + if (document.body) { + observer.observe(document.body, { childList: true, subtree: true }); + } } catch(e) { console.error('Failed to inject token:', e); } @@ -199,6 +229,19 @@ export default function HomeScreen() { setIsLoading(false); }; + // Handle messages from WebView (session expired detection) + const handleWebViewMessage = useCallback((event: { nativeEvent: { data: string } }) => { + try { + const message = JSON.parse(event.nativeEvent.data); + if (message.type === 'SESSION_EXPIRED') { + console.log('WebView reported session expired, refreshing token...'); + handleTokenRefresh(); + } + } catch { + // Ignore non-JSON messages + } + }, [handleTokenRefresh]); + // Wait for token to load if (!isTokenLoaded) { return ( @@ -285,6 +328,7 @@ export default function HomeScreen() { onHttpError={handleError} onNavigationStateChange={handleNavigationStateChange} onShouldStartLoadWithRequest={handleShouldStartLoadWithRequest} + onMessage={handleWebViewMessage} javaScriptEnabled={true} domStorageEnabled={true} startInLoadingState={true} diff --git a/services/api.ts b/services/api.ts index 0cc66e4..26d84f4 100644 --- a/services/api.ts +++ b/services/api.ts @@ -100,13 +100,20 @@ class ApiService { const userName = await SecureStore.getItemAsync('userName'); const password = await SecureStore.getItemAsync('userPassword'); + console.log('[API] refreshToken - userName:', userName ? 'exists' : 'missing'); + console.log('[API] refreshToken - password:', password ? 'exists' : 'missing'); + if (!userName || !password) { + console.log('[API] refreshToken - NO_CREDENTIALS'); return { ok: false, error: { message: 'No stored credentials', code: 'NO_CREDENTIALS' } }; } - console.log('Refreshing token for user:', userName); - return await this.login(userName, password); + console.log('[API] Refreshing token for user:', userName); + const result = await this.login(userName, password); + console.log('[API] refreshToken result:', result.ok ? 'SUCCESS' : result.error?.message); + return result; } catch (error) { + console.error('[API] refreshToken error:', error); return { ok: false, error: { message: 'Failed to refresh token', code: 'REFRESH_ERROR' }