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
This commit is contained in:
parent
f7cc2973e1
commit
5f10e9fb54
|
|
@ -76,6 +76,12 @@ const checkConnection = () => {
|
||||||
if (sessionId && email) {
|
if (sessionId && email) {
|
||||||
isConnected.value = true;
|
isConnected.value = true;
|
||||||
connectedEmail.value = email;
|
connectedEmail.value = email;
|
||||||
|
} else {
|
||||||
|
// Clear any partial session data
|
||||||
|
sessionStorage.removeItem('emailSessionId');
|
||||||
|
sessionStorage.removeItem('connectedEmail');
|
||||||
|
isConnected.value = false;
|
||||||
|
connectedEmail.value = '';
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -181,6 +181,15 @@ const truncateText = (text: string, maxLength: number = 200) => {
|
||||||
};
|
};
|
||||||
|
|
||||||
const loadEmails = async () => {
|
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;
|
loading.value = true;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
@ -196,18 +205,19 @@ const loadEmails = async () => {
|
||||||
body: {
|
body: {
|
||||||
clientEmail: props.interest['Email Address'],
|
clientEmail: props.interest['Email Address'],
|
||||||
interestId: props.interest.Id,
|
interestId: props.interest.Id,
|
||||||
sessionId: getSessionId(),
|
sessionId: sessionId,
|
||||||
limit: 50
|
limit: 20
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
if (response.success) {
|
if (response.success) {
|
||||||
threads.value = response.threads;
|
threads.value = response.threads || [];
|
||||||
}
|
}
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
console.error('Failed to load emails:', error);
|
console.error('Failed to load emails:', error);
|
||||||
if (error.data?.statusMessage?.includes('Email credentials not found')) {
|
if (error.data?.statusMessage?.includes('Email credentials not found')) {
|
||||||
// Don't show error, parent component should handle reconnection
|
// Don't show error, parent component should handle reconnection
|
||||||
|
threads.value = [];
|
||||||
} else {
|
} else {
|
||||||
toast.error(error.data?.statusMessage || 'Failed to load email history');
|
toast.error(error.data?.statusMessage || 'Failed to load email history');
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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 <container-name>`
|
||||||
|
2. **Verify environment variables are set correctly**
|
||||||
|
3. **Ensure Documenso API credentials are valid**
|
||||||
|
4. **Try disconnecting and reconnecting email credentials**
|
||||||
|
|
@ -36,10 +36,12 @@ export default defineEventHandler(async (event) => {
|
||||||
// Get encrypted credentials from session
|
// Get encrypted credentials from session
|
||||||
const encryptedCredentials = getCredentialsFromSession(sessionId);
|
const encryptedCredentials = getCredentialsFromSession(sessionId);
|
||||||
if (!encryptedCredentials) {
|
if (!encryptedCredentials) {
|
||||||
throw createError({
|
// Return empty results instead of throwing error
|
||||||
statusCode: 401,
|
return {
|
||||||
statusMessage: "Email credentials not found. Please reconnect."
|
success: true,
|
||||||
});
|
emails: [],
|
||||||
|
threads: []
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// Decrypt credentials
|
// Decrypt credentials
|
||||||
|
|
|
||||||
|
|
@ -80,10 +80,17 @@ export default defineEventHandler(async (event) => {
|
||||||
const berthNumbers = berths.map(b => b['Mooring Number']).join(', ');
|
const berthNumbers = berths.map(b => b['Mooring Number']).join(', ');
|
||||||
|
|
||||||
// Documenso API configuration
|
// Documenso API configuration
|
||||||
const documensoApiKey = process.env.NUXT_DOCUMENSO_API_KEY || 'api_malptg62zqyb0wrp';
|
const documensoApiKey = process.env.NUXT_DOCUMENSO_API_KEY;
|
||||||
const documensoBaseUrl = process.env.NUXT_DOCUMENSO_BASE_URL || 'https://signatures.portnimara.dev';
|
const documensoBaseUrl = process.env.NUXT_DOCUMENSO_BASE_URL;
|
||||||
const templateId = '9';
|
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)
|
// 1. Get template (optional - just to verify it exists)
|
||||||
try {
|
try {
|
||||||
const templateResponse = await fetch(`${documensoBaseUrl}/api/v1/templates/${templateId}`, {
|
const templateResponse = await fetch(`${documensoBaseUrl}/api/v1/templates/${templateId}`, {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue