AI Analysis and Content Strategy fixes. Enhanced Strategy Routes refactoring.
This commit is contained in:
145
backend/api/content_planning/docs/AUTHENTICATION_FIX_COMPLETE.md
Normal file
145
backend/api/content_planning/docs/AUTHENTICATION_FIX_COMPLETE.md
Normal file
@@ -0,0 +1,145 @@
|
||||
# Authentication Fix - Complete Summary
|
||||
|
||||
## Problem
|
||||
Users were being logged out when navigating to content-planning due to 401 authentication errors. Requests were being made before Clerk authentication was ready, causing the frontend's 401 error handler to automatically sign out users.
|
||||
|
||||
## Root Causes
|
||||
|
||||
1. **Frontend Components**: Making API calls immediately on mount without checking if Clerk is loaded or user is authenticated
|
||||
2. **EventSource Limitations**: EventSource API doesn't support custom headers, so streaming endpoints couldn't receive auth tokens
|
||||
3. **API Service**: No guards to prevent requests when authentication isn't ready
|
||||
|
||||
## Solutions Applied
|
||||
|
||||
### 1. Frontend Component Authentication Checks ✅
|
||||
|
||||
**Files Updated:**
|
||||
- `ContentStrategyTab.tsx`
|
||||
- `ContentPlanningDashboard.tsx`
|
||||
|
||||
**Changes:**
|
||||
- Added `useAuth` hook from Clerk
|
||||
- Check `isLoaded` and `isSignedIn` before making API calls
|
||||
- Show loading state while waiting for Clerk
|
||||
- Show warning if user is not signed in
|
||||
|
||||
```typescript
|
||||
const { isLoaded, isSignedIn } = useAuth();
|
||||
|
||||
useEffect(() => {
|
||||
if (!isLoaded) return; // Wait for Clerk
|
||||
if (!isSignedIn) return; // Wait for authentication
|
||||
|
||||
// Only make API calls if authenticated
|
||||
loadInitialData();
|
||||
}, [isLoaded, isSignedIn]);
|
||||
```
|
||||
|
||||
### 2. API Service Authentication Guards ✅
|
||||
|
||||
**File Updated:**
|
||||
- `contentPlanningApi.ts`
|
||||
|
||||
**Changes:**
|
||||
- Added authentication checks in `getStrategies()` method
|
||||
- Check if `authTokenGetter` is set before making requests
|
||||
- Check if token is available before making requests
|
||||
- Throw descriptive errors if authentication isn't ready
|
||||
|
||||
```typescript
|
||||
async getStrategies(userId?: number) {
|
||||
const { getAuthTokenGetter } = await import('../api/client');
|
||||
const tokenGetter = getAuthTokenGetter();
|
||||
|
||||
if (!tokenGetter) {
|
||||
throw new Error('Authentication not ready. Please wait for sign-in to complete.');
|
||||
}
|
||||
|
||||
const token = await tokenGetter();
|
||||
if (!token) {
|
||||
throw new Error('Authentication required. Please sign in to access content planning features.');
|
||||
}
|
||||
|
||||
// Make request...
|
||||
}
|
||||
```
|
||||
|
||||
### 3. EventSource Authentication Support ✅
|
||||
|
||||
**Files Updated:**
|
||||
- `contentPlanningApi.ts` (frontend)
|
||||
- `streaming_endpoints.py` (backend)
|
||||
|
||||
**Changes:**
|
||||
- Updated `streamStrategicIntelligence()` and `streamKeywordResearch()` to pass token as query parameter
|
||||
- Updated backend streaming endpoints to use `get_current_user_with_query_token` instead of `get_current_user`
|
||||
- Added `Request` import to streaming endpoints
|
||||
|
||||
**Frontend:**
|
||||
```typescript
|
||||
// EventSource doesn't support custom headers, so we pass token as query parameter
|
||||
const url = `${this.baseURL}/enhanced-strategies/stream/strategic-intelligence?user_id=${userId || 1}&token=${encodeURIComponent(token)}`;
|
||||
return new EventSource(url);
|
||||
```
|
||||
|
||||
**Backend:**
|
||||
```python
|
||||
@router.get("/stream/strategic-intelligence")
|
||||
async def stream_strategic_intelligence(
|
||||
request: Request,
|
||||
current_user: Dict[str, Any] = Depends(get_current_user_with_query_token),
|
||||
db: Session = Depends(get_db)
|
||||
):
|
||||
```
|
||||
|
||||
### 4. Client Module Export ✅
|
||||
|
||||
**File Updated:**
|
||||
- `client.ts`
|
||||
|
||||
**Changes:**
|
||||
- Added `getAuthTokenGetter()` export function to allow API services to check if auth is ready
|
||||
|
||||
```typescript
|
||||
export const getAuthTokenGetter = (): (() => Promise<string | null>) | null => {
|
||||
return authTokenGetter;
|
||||
};
|
||||
```
|
||||
|
||||
## Endpoints Fixed
|
||||
|
||||
1. ✅ `GET /api/content-planning/enhanced-strategies/` - Regular HTTP (headers)
|
||||
2. ✅ `GET /api/content-planning/enhanced-strategies/stream/strategic-intelligence` - EventSource (query param)
|
||||
3. ✅ `GET /api/content-planning/enhanced-strategies/stream/keyword-research` - EventSource (query param)
|
||||
|
||||
## Authentication Flow
|
||||
|
||||
1. **Component Mounts** → Checks `isLoaded` and `isSignedIn`
|
||||
2. **If Not Ready** → Shows loading state, doesn't make API calls
|
||||
3. **If Ready** → Makes API calls
|
||||
4. **API Service** → Checks if `authTokenGetter` is set and token is available
|
||||
5. **If Not Ready** → Throws error (caught by component, shows message)
|
||||
6. **If Ready** → Makes request with auth token
|
||||
7. **Backend** → Validates token and processes request
|
||||
|
||||
## Result
|
||||
|
||||
✅ **No more premature API calls** - Components wait for authentication
|
||||
✅ **No more 401 errors** - Requests only made when authenticated
|
||||
✅ **No more unwanted logouts** - Authentication verified before API calls
|
||||
✅ **EventSource support** - Streaming endpoints work with query parameter tokens
|
||||
✅ **Better UX** - Loading states while waiting for authentication
|
||||
|
||||
## Testing Checklist
|
||||
|
||||
- [x] Component waits for Clerk to load before making API calls
|
||||
- [x] Component checks if user is signed in before making API calls
|
||||
- [x] API service checks if auth token is available
|
||||
- [x] EventSource requests include token in query parameter
|
||||
- [x] Backend streaming endpoints accept tokens from query parameters
|
||||
- [x] Regular HTTP requests use Authorization header
|
||||
- [x] Error handling for unauthenticated requests
|
||||
|
||||
## Status: ✅ COMPLETE
|
||||
|
||||
All authentication issues have been resolved. Users can now navigate to content-planning without being logged out.
|
||||
Reference in New Issue
Block a user