Fix chat history authentication and conversation saving
- Fix critical async/await bug in chat API token verification - Add comprehensive authentication debugging logs - Fix conversations API Zod schema validation for query parameters - Remove problematic CircularProgress import causing build warnings - Improve error handling and user feedback in chat component The main issue was that verifyToken() was called without await, causing the chat API to receive a Promise object instead of the user payload, resulting in undefined userId and failed conversation persistence. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -14,8 +14,8 @@ const createConversationSchema = z.object({
|
|||||||
|
|
||||||
const getConversationsSchema = z.object({
|
const getConversationsSchema = z.object({
|
||||||
language: z.enum(['ro', 'en']).optional(),
|
language: z.enum(['ro', 'en']).optional(),
|
||||||
limit: z.string().transform(Number).pipe(z.number().min(1).max(50)).optional().default('20'),
|
limit: z.string().optional().default('20').transform(Number).pipe(z.number().min(1).max(50)),
|
||||||
offset: z.string().transform(Number).pipe(z.number().min(0)).optional().default('0'),
|
offset: z.string().optional().default('0').transform(Number).pipe(z.number().min(0)),
|
||||||
})
|
})
|
||||||
|
|
||||||
// GET /api/chat/conversations - List user's conversations
|
// GET /api/chat/conversations - List user's conversations
|
||||||
@@ -44,7 +44,11 @@ export async function GET(request: NextRequest) {
|
|||||||
|
|
||||||
// Parse query parameters
|
// Parse query parameters
|
||||||
const url = new URL(request.url)
|
const url = new URL(request.url)
|
||||||
const queryParams = Object.fromEntries(url.searchParams.entries())
|
const queryParams = {
|
||||||
|
language: url.searchParams.get('language') || undefined,
|
||||||
|
limit: url.searchParams.get('limit') || '20',
|
||||||
|
offset: url.searchParams.get('offset') || '0'
|
||||||
|
}
|
||||||
const { language, limit, offset } = getConversationsSchema.parse(queryParams)
|
const { language, limit, offset } = getConversationsSchema.parse(queryParams)
|
||||||
|
|
||||||
// Build where clause
|
// Build where clause
|
||||||
|
|||||||
@@ -29,15 +29,21 @@ export async function POST(request: NextRequest) {
|
|||||||
// Try to get user from authentication (optional for backward compatibility)
|
// Try to get user from authentication (optional for backward compatibility)
|
||||||
let userId: string | null = null
|
let userId: string | null = null
|
||||||
const authHeader = request.headers.get('authorization')
|
const authHeader = request.headers.get('authorization')
|
||||||
|
console.log('Chat API - authHeader present:', !!authHeader)
|
||||||
if (authHeader?.startsWith('Bearer ')) {
|
if (authHeader?.startsWith('Bearer ')) {
|
||||||
try {
|
try {
|
||||||
const token = authHeader.substring(7)
|
const token = authHeader.substring(7)
|
||||||
const payload = verifyToken(token)
|
console.log('Chat API - token extracted, length:', token.length)
|
||||||
|
const payload = await verifyToken(token)
|
||||||
|
console.log('Chat API - token payload:', payload)
|
||||||
userId = payload.userId
|
userId = payload.userId
|
||||||
|
console.log('Chat API - userId extracted from token:', userId)
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
// Continue without authentication for backward compatibility
|
// Continue without authentication for backward compatibility
|
||||||
console.log('Chat without authentication')
|
console.log('Chat API - authentication failed:', error.message)
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
console.log('Chat API - no valid auth header')
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle conversation logic
|
// Handle conversation logic
|
||||||
@@ -97,6 +103,11 @@ export async function POST(request: NextRequest) {
|
|||||||
const aiResponse = await generateBiblicalResponse(message, locale, conversationHistory)
|
const aiResponse = await generateBiblicalResponse(message, locale, conversationHistory)
|
||||||
|
|
||||||
// Save messages to database if user is authenticated
|
// Save messages to database if user is authenticated
|
||||||
|
console.log('Chat API - conversation saving check:', {
|
||||||
|
userId: userId ? 'present' : 'null',
|
||||||
|
finalConversationId: finalConversationId ? 'present' : 'null',
|
||||||
|
willSave: !!(userId && finalConversationId)
|
||||||
|
})
|
||||||
if (userId && finalConversationId) {
|
if (userId && finalConversationId) {
|
||||||
await prisma.$transaction([
|
await prisma.$transaction([
|
||||||
// Save user message
|
// Save user message
|
||||||
|
|||||||
@@ -24,7 +24,6 @@ import {
|
|||||||
DialogTitle,
|
DialogTitle,
|
||||||
DialogContent,
|
DialogContent,
|
||||||
DialogActions,
|
DialogActions,
|
||||||
CircularProgress,
|
|
||||||
} from '@mui/material'
|
} from '@mui/material'
|
||||||
import {
|
import {
|
||||||
Chat,
|
Chat,
|
||||||
@@ -139,6 +138,7 @@ export default function FloatingChat() {
|
|||||||
const checkAuthStatus = useCallback(async () => {
|
const checkAuthStatus = useCallback(async () => {
|
||||||
try {
|
try {
|
||||||
const token = localStorage.getItem('authToken')
|
const token = localStorage.getItem('authToken')
|
||||||
|
console.log('Chat - checkAuthStatus: token from localStorage:', token ? 'present' : 'null')
|
||||||
if (token) {
|
if (token) {
|
||||||
// Verify token with the server
|
// Verify token with the server
|
||||||
const response = await fetch('/api/auth/me', {
|
const response = await fetch('/api/auth/me', {
|
||||||
@@ -146,18 +146,25 @@ export default function FloatingChat() {
|
|||||||
'Authorization': `Bearer ${token}`
|
'Authorization': `Bearer ${token}`
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
console.log('Chat - auth verification response:', response.ok)
|
||||||
|
|
||||||
if (response.ok) {
|
if (response.ok) {
|
||||||
setAuthToken(token)
|
setAuthToken(token)
|
||||||
setIsAuthenticated(true)
|
setIsAuthenticated(true)
|
||||||
|
console.log('Chat - Auth state set: authenticated')
|
||||||
} else {
|
} else {
|
||||||
localStorage.removeItem('authToken')
|
localStorage.removeItem('authToken')
|
||||||
setIsAuthenticated(false)
|
setIsAuthenticated(false)
|
||||||
setAuthToken(null)
|
setAuthToken(null)
|
||||||
|
console.log('Chat - Auth verification failed, cleared state')
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
console.log('Chat - No token in localStorage')
|
||||||
|
setIsAuthenticated(false)
|
||||||
|
setAuthToken(null)
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Auth check failed:', error)
|
console.error('Chat - Auth check failed:', error)
|
||||||
setIsAuthenticated(false)
|
setIsAuthenticated(false)
|
||||||
setAuthToken(null)
|
setAuthToken(null)
|
||||||
}
|
}
|
||||||
@@ -342,8 +349,12 @@ export default function FloatingChat() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Add authentication if available
|
// Add authentication if available
|
||||||
|
console.log('Chat - authToken value:', authToken ? 'present' : 'null')
|
||||||
if (authToken) {
|
if (authToken) {
|
||||||
headers['Authorization'] = `Bearer ${authToken}`
|
headers['Authorization'] = `Bearer ${authToken}`
|
||||||
|
console.log('Chat - Authorization header added')
|
||||||
|
} else {
|
||||||
|
console.log('Chat - No authToken, skipping Authorization header')
|
||||||
}
|
}
|
||||||
|
|
||||||
const response = await fetch('/api/chat', {
|
const response = await fetch('/api/chat', {
|
||||||
@@ -569,7 +580,7 @@ export default function FloatingChat() {
|
|||||||
</Box>
|
</Box>
|
||||||
) : isLoadingConversations ? (
|
) : isLoadingConversations ? (
|
||||||
<Box sx={{ display: 'flex', justifyContent: 'center', py: 3 }}>
|
<Box sx={{ display: 'flex', justifyContent: 'center', py: 3 }}>
|
||||||
<CircularProgress size={24} />
|
⟳
|
||||||
</Box>
|
</Box>
|
||||||
) : conversations.length === 0 ? (
|
) : conversations.length === 0 ? (
|
||||||
<Box sx={{ textAlign: 'center', py: 3 }}>
|
<Box sx={{ textAlign: 'center', py: 3 }}>
|
||||||
|
|||||||
Reference in New Issue
Block a user