LinkedIn Account Creation Fix Summary
Issue Analysis
The user reported that they were trying to add a LinkedIn account but couldn't see it in their database despite successful API calls in the logs. After analyzing the logs and code, I identified the root cause:
Root Cause
The OAuth callback handler was trying to make a POST request to the same server (/api/accounts/callback
) from within the callback handler, which was causing a 500 error. This prevented the OAuth data from being properly processed and stored in the database.
Key Problems Identified
Callback Handler Architecture Issue: The backend callback handler was attempting to make an internal API call to complete the OAuth flow, which created a circular dependency and failed.
Missing Session Management: There was no proper session management to handle the OAuth data between the callback and the final account creation.
Frontend-Backend Communication Gap: The frontend was expecting direct URL parameter handling, but the backend was trying to process everything internally.
Solution Implemented
1. Backend OAuth Callback Handler Redesign
File: backend/app.py
- Simplified Callback Flow: Removed the internal API call attempt and instead store OAuth data in Flask session
- Proper Redirect: Redirect back to the frontend with success/error indicators
- Session Storage: Store OAuth data (
code
,state
,social_network
) in Flask session for later retrieval
# Store the OAuth data in the session for the frontend to pick up
from flask import session
session['oauth_data'] = {
'code': code,
'state': state,
'social_network': 'LinkedIn'
}
# Redirect to frontend with success indication
from flask import redirect
redirect_url = f"{request.host_url.rstrip('/')}?oauth_success=true&from=linkedin"
return redirect(redirect_url)
2. Frontend Callback Handler Update
File: frontend/src/components/LinkedInAccount/LinkedInCallbackHandler.jsx
- Enhanced Parameter Handling: Added support for
oauth_success
andfrom
parameters - Session Data Retrieval: Implemented proper session data retrieval via API endpoint
- Improved Error Handling: Added comprehensive error handling and logging
// Check if we're coming from LinkedIn OAuth
if (from === 'linkedin') {
if (oauthSuccess === 'true') {
// Get OAuth data from backend session
const sessionResponse = await apiClient.get('/accounts/session-data');
if (sessionResponse.data.success && sessionResponse.data.oauth_data) {
const oauthData = sessionResponse.data.oauth_data;
// Process OAuth callback
}
}
}
3. Session Data API Endpoint
File: backend/api/accounts.py
- New Endpoint: Added
/api/accounts/session-data
endpoint to retrieve OAuth data from session - Proper Authentication: Ensured JWT protection for the endpoint
- Error Handling: Added comprehensive error handling
@accounts_bp.route('/session-data', methods=['GET'])
@jwt_required()
def get_session_data():
from flask import session
oauth_data = session.get('oauth_data', None)
if oauth_data:
return jsonify({
'success': True,
'oauth_data': oauth_data
}), 200
else:
return jsonify({
'success': False,
'message': 'No OAuth data found in session'
}), 404
4. Enhanced Logging and Debugging
Files: Multiple files updated with comprehensive logging
- Backend Logging: Added detailed logging throughout the OAuth flow
- Frontend Logging: Enhanced frontend callback handler with detailed debugging
- Error Tracking: Improved error tracking and reporting
Technical Changes Summary
Backend Changes
- OAuth Callback Handler: Completely redesigned to use session-based approach
- Session Management: Implemented proper Flask session management
- API Endpoint: Added session data retrieval endpoint
- Error Handling: Enhanced error handling and logging
Frontend Changes
- Callback Handler: Updated to handle new URL parameters and session data
- Error Handling: Improved error handling and user feedback
- Logging: Enhanced debugging capabilities
Testing
- Test Script: Created
backend/test_oauth_callback.py
for testing the callback flow - Integration Testing: Added comprehensive integration testing
Expected Behavior After Fix
Successful Account Creation Flow
- User clicks "Connect LinkedIn Account"
- User is redirected to LinkedIn for authentication
- After successful authentication, LinkedIn redirects back to
/auth/callback
- Backend stores OAuth data in session and redirects to frontend with
?oauth_success=true&from=linkedin
- Frontend detects the callback parameters and retrieves OAuth data from backend
- Frontend makes API call to
/api/accounts/callback
with OAuth data - Backend processes OAuth data, exchanges code for access token, and stores account in database
- User sees success message and is redirected to sources page
Error Handling
- Authentication Error: If LinkedIn authentication fails, user is redirected back with error parameter
- Missing Parameters: If required parameters are missing, appropriate error is shown
- Database Issues: If database insertion fails, error is logged and user is informed
- Session Issues: If session data is missing, user is prompted to try again
Verification Steps
To verify the fix works:
- Start the backend server:
python backend/app.py
- Start the frontend server:
npm run dev
(in frontend directory) - Navigate to the application: Open browser to the application URL
- Add LinkedIn Account: Click "Connect LinkedIn Account" button
- Complete Authentication: Follow through LinkedIn authentication process
- Verify Success: Check that the account appears in the database and UI
Testing with Test Script
cd backend
python test_oauth_callback.py
Monitoring and Debugging
Backend Logs
Look for these key log messages:
π [OAuth] Direct callback handler triggered
π [OAuth] OAuth data stored in session
π [OAuth] Account linked successfully for user: [user_id]
Frontend Logs
Look for these key log messages:
π [Frontend] LinkedIn callback handler started
π [Frontend] OAuth success detected, fetching session data...
π [Frontend] LinkedIn account linked successfully!
Database Verification
After successful account creation, verify the account exists in the Social_network
table:
SELECT * FROM Social_network WHERE id_utilisateur = '[user_id]' AND social_network = 'LinkedIn';
Conclusion
The fix addresses the core issue by implementing a proper session-based OAuth callback flow that avoids the circular dependency problem. The solution is more robust, maintainable, and provides better error handling and user feedback.
The key improvements are:
- Proper Session Management: OAuth data is securely stored and retrieved
- Clean Architecture: Separation of concerns between frontend and backend
- Better Error Handling: Comprehensive error handling throughout the flow
- Enhanced Logging: Detailed logging for debugging and monitoring
- User Experience: Clear feedback and error messages for users
This fix should resolve the issue where accounts were not appearing in the database despite successful API calls.