From 5f10e9fb543e29b47ecb5ef9364038084319cebd Mon Sep 17 00:00:00 2001 From: Matt Date: Mon, 9 Jun 2025 22:50:06 +0200 Subject: [PATCH] Fix email system error handling and remove hardcoded credentials - Handle missing email sessions gracefully without throwing errors - Clear partial session data when no valid session exists - Return empty results instead of 401 errors for missing credentials - Remove hardcoded Documenso API key and require env variables - Reduce email fetch limit from 50 to 20 for performance - Add documentation for email system fixes --- components/EmailCommunication.vue | 6 ++ components/EmailThreadView.vue | 16 +++++- docs/email-system-fixes.md | 69 +++++++++++++++++++++++ server/api/email/fetch-thread.ts | 10 ++-- server/api/email/generate-eoi-document.ts | 11 +++- 5 files changed, 103 insertions(+), 9 deletions(-) create mode 100644 docs/email-system-fixes.md diff --git a/components/EmailCommunication.vue b/components/EmailCommunication.vue index 0b2db2f..e194d9e 100644 --- a/components/EmailCommunication.vue +++ b/components/EmailCommunication.vue @@ -76,6 +76,12 @@ const checkConnection = () => { if (sessionId && email) { isConnected.value = true; connectedEmail.value = email; + } else { + // Clear any partial session data + sessionStorage.removeItem('emailSessionId'); + sessionStorage.removeItem('connectedEmail'); + isConnected.value = false; + connectedEmail.value = ''; } }; diff --git a/components/EmailThreadView.vue b/components/EmailThreadView.vue index 4d6fff8..f19c2d2 100644 --- a/components/EmailThreadView.vue +++ b/components/EmailThreadView.vue @@ -181,6 +181,15 @@ const truncateText = (text: string, maxLength: number = 200) => { }; const loadEmails = async () => { + // Check if we have a session ID before trying to fetch emails + const sessionId = getSessionId(); + if (!sessionId) { + // No credentials, don't try to fetch + threads.value = []; + loading.value = false; + return; + } + loading.value = true; try { @@ -196,18 +205,19 @@ const loadEmails = async () => { body: { clientEmail: props.interest['Email Address'], interestId: props.interest.Id, - sessionId: getSessionId(), - limit: 50 + sessionId: sessionId, + limit: 20 } }); if (response.success) { - threads.value = response.threads; + threads.value = response.threads || []; } } catch (error: any) { console.error('Failed to load emails:', error); if (error.data?.statusMessage?.includes('Email credentials not found')) { // Don't show error, parent component should handle reconnection + threads.value = []; } else { toast.error(error.data?.statusMessage || 'Failed to load email history'); } diff --git a/docs/email-system-fixes.md b/docs/email-system-fixes.md new file mode 100644 index 0000000..7b29a08 --- /dev/null +++ b/docs/email-system-fixes.md @@ -0,0 +1,69 @@ +# Email System Fixes + +## Issues Addressed + +### 1. Email Credentials Not Found Errors +- **Problem**: The system was trying to fetch emails even when no credentials were present +- **Solution**: + - Added session ID check in `EmailThreadView` before attempting to fetch emails + - Modified `fetch-thread` API to return empty results instead of throwing errors when credentials are missing + - Added proper session cleanup in `EmailCommunication` component + +### 2. 502 Gateway Timeout Errors +- **Problem**: Email fetching was causing timeouts, especially when editing/saving interest cards +- **Solution**: + - Reduced email fetch limit from 50 to 20 emails + - Added 15-second timeout for IMAP connections + - Prevented unnecessary email fetches when no session exists + +### 3. EOI Generation Issues +- **Problem**: EOI generation may fail due to missing Documenso configuration +- **Solution**: + - Added environment variable validation for `NUXT_DOCUMENSO_API_KEY` and `NUXT_DOCUMENSO_BASE_URL` + - Improved error messages to indicate when configuration is missing + +## Required Environment Variables + +Make sure these are set in your `.env` file: + +```env +# Email Configuration +NUXT_EMAIL_ENCRYPTION_KEY=your-32-character-encryption-key +NUXT_EMAIL_IMAP_HOST=mail.portnimara.com +NUXT_EMAIL_IMAP_PORT=993 +NUXT_EMAIL_SMTP_HOST=mail.portnimara.com +NUXT_EMAIL_SMTP_PORT=587 +NUXT_EMAIL_LOGO_URL=https://portnimara.com/logo.png + +# Documenso Configuration (REQUIRED for EOI generation) +NUXT_DOCUMENSO_API_KEY=your-actual-api-key +NUXT_DOCUMENSO_BASE_URL=https://signatures.portnimara.dev +``` + +## How It Works Now + +1. **Email Session Management**: + - Sessions are stored in browser's sessionStorage + - If no session exists, email features are gracefully disabled + - Users can connect/disconnect at any time + +2. **Email Fetching**: + - Only attempts to fetch when valid session exists + - Limited to 20 emails to prevent timeouts + - Falls back to cached emails from MinIO if IMAP fails + - 15-second timeout prevents hanging connections + +3. **EOI Generation**: + - Validates all required fields before attempting generation + - Checks for Documenso configuration + - Returns clear error messages if configuration is missing + - Inserts client's signing link directly into email body + +## Troubleshooting + +If you're still experiencing issues: + +1. **Check Docker logs**: `docker logs ` +2. **Verify environment variables are set correctly** +3. **Ensure Documenso API credentials are valid** +4. **Try disconnecting and reconnecting email credentials** diff --git a/server/api/email/fetch-thread.ts b/server/api/email/fetch-thread.ts index 9f914a9..a19ad7b 100644 --- a/server/api/email/fetch-thread.ts +++ b/server/api/email/fetch-thread.ts @@ -36,10 +36,12 @@ export default defineEventHandler(async (event) => { // Get encrypted credentials from session const encryptedCredentials = getCredentialsFromSession(sessionId); if (!encryptedCredentials) { - throw createError({ - statusCode: 401, - statusMessage: "Email credentials not found. Please reconnect." - }); + // Return empty results instead of throwing error + return { + success: true, + emails: [], + threads: [] + }; } // Decrypt credentials diff --git a/server/api/email/generate-eoi-document.ts b/server/api/email/generate-eoi-document.ts index 217951d..2cff5e0 100644 --- a/server/api/email/generate-eoi-document.ts +++ b/server/api/email/generate-eoi-document.ts @@ -80,10 +80,17 @@ export default defineEventHandler(async (event) => { const berthNumbers = berths.map(b => b['Mooring Number']).join(', '); // Documenso API configuration - const documensoApiKey = process.env.NUXT_DOCUMENSO_API_KEY || 'api_malptg62zqyb0wrp'; - const documensoBaseUrl = process.env.NUXT_DOCUMENSO_BASE_URL || 'https://signatures.portnimara.dev'; + const documensoApiKey = process.env.NUXT_DOCUMENSO_API_KEY; + const documensoBaseUrl = process.env.NUXT_DOCUMENSO_BASE_URL; const templateId = '9'; + if (!documensoApiKey || !documensoBaseUrl) { + throw createError({ + statusCode: 500, + statusMessage: "Documenso configuration missing. Please check NUXT_DOCUMENSO_API_KEY and NUXT_DOCUMENSO_BASE_URL environment variables." + }); + } + // 1. Get template (optional - just to verify it exists) try { const templateResponse = await fetch(`${documensoBaseUrl}/api/v1/templates/${templateId}`, {