Add session expired detection and auto-refresh in WebView
- Monitor page content for "session expired" patterns - Send message to React Native when detected - Auto-refresh token and reload WebView - Add logging to refreshToken for debugging
This commit is contained in:
parent
bc33230739
commit
173c0a8262
@ -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}
|
||||
|
||||
@ -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' }
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user