SignIn
This commit is contained in:
parent
aadc8ebc6b
commit
54802eaa4f
@ -97,16 +97,59 @@ export async function GET(
|
||||
if (attachment.content) {
|
||||
attachmentBuffer = Buffer.from(attachment.content, 'base64');
|
||||
} else {
|
||||
// Need to fetch from Graph API - this requires the attachment ID
|
||||
// For now, return error as we need to modify the email fetching to include attachment IDs
|
||||
logger.error('[ATTACHMENT] Graph API attachment requires ID but content not cached', {
|
||||
// Need to fetch from Graph API - try to get attachment ID from email metadata
|
||||
// First, re-fetch the email to get attachment IDs if available
|
||||
logger.debug('[ATTACHMENT] Attachment content not cached, fetching from Graph API', {
|
||||
emailId,
|
||||
attachmentIndex: attachmentIdx,
|
||||
mailCredentialIdHash: graphCheck.mailCredentialId ? Buffer.from(graphCheck.mailCredentialId).toString('base64').slice(0, 12) : null,
|
||||
});
|
||||
return NextResponse.json(
|
||||
{ error: "Attachment content not available. Please refresh the email to load attachment data." },
|
||||
{ status: 404 }
|
||||
);
|
||||
|
||||
try {
|
||||
// Re-fetch the email with full attachment data
|
||||
const { fetchGraphEmail, fetchGraphAttachment } = await import('@/lib/services/microsoft-graph-mail');
|
||||
const graphMessage = await fetchGraphEmail(graphCheck.mailCredentialId, emailId);
|
||||
|
||||
if (!graphMessage.attachments || attachmentIdx >= graphMessage.attachments.length) {
|
||||
return NextResponse.json(
|
||||
{ error: "Attachment not found" },
|
||||
{ status: 404 }
|
||||
);
|
||||
}
|
||||
|
||||
const graphAttachment = graphMessage.attachments[attachmentIdx];
|
||||
|
||||
// If still no contentBytes, try fetching by attachment ID
|
||||
if (!graphAttachment.contentBytes && graphAttachment.id) {
|
||||
const attachmentData = await fetchGraphAttachment(
|
||||
graphCheck.mailCredentialId,
|
||||
emailId,
|
||||
graphAttachment.id
|
||||
);
|
||||
attachmentBuffer = Buffer.from(attachmentData.contentBytes, 'base64');
|
||||
} else if (graphAttachment.contentBytes) {
|
||||
attachmentBuffer = Buffer.from(graphAttachment.contentBytes, 'base64');
|
||||
} else {
|
||||
logger.error('[ATTACHMENT] Graph API attachment has no content and no ID', {
|
||||
emailId,
|
||||
attachmentIndex: attachmentIdx,
|
||||
});
|
||||
return NextResponse.json(
|
||||
{ error: "Attachment content not available" },
|
||||
{ status: 404 }
|
||||
);
|
||||
}
|
||||
} catch (fetchError) {
|
||||
logger.error('[ATTACHMENT] Error fetching attachment from Graph API', {
|
||||
emailId,
|
||||
attachmentIndex: attachmentIdx,
|
||||
error: fetchError instanceof Error ? fetchError.message : String(fetchError),
|
||||
});
|
||||
return NextResponse.json(
|
||||
{ error: "Failed to fetch attachment from Microsoft Graph API" },
|
||||
{ status: 500 }
|
||||
);
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
logger.error('[ATTACHMENT] Error fetching Graph API attachment', {
|
||||
|
||||
@ -185,6 +185,7 @@ export async function fetchGraphEmails(
|
||||
|
||||
/**
|
||||
* Fetch a single email by ID from Microsoft Graph
|
||||
* Automatically fetches attachment content if not included in initial response
|
||||
*/
|
||||
export async function fetchGraphEmail(
|
||||
mailCredentialId: string,
|
||||
@ -199,7 +200,45 @@ export async function fetchGraphEmail(
|
||||
},
|
||||
});
|
||||
|
||||
return response.data;
|
||||
const message = response.data;
|
||||
|
||||
// If email has attachments but they don't have contentBytes, fetch them individually
|
||||
if (message.hasAttachments && message.attachments && Array.isArray(message.attachments)) {
|
||||
const attachmentsWithContent = await Promise.all(
|
||||
message.attachments.map(async (attachment: any) => {
|
||||
// If contentBytes is missing, fetch the attachment content
|
||||
if (!attachment.contentBytes && attachment.id) {
|
||||
try {
|
||||
logger.debug('Fetching attachment content from Graph API', {
|
||||
messageId,
|
||||
attachmentId: attachment.id,
|
||||
attachmentName: attachment.name,
|
||||
});
|
||||
|
||||
const attachmentData = await fetchGraphAttachment(mailCredentialId, messageId, attachment.id);
|
||||
return {
|
||||
...attachment,
|
||||
contentBytes: attachmentData.contentBytes,
|
||||
};
|
||||
} catch (error) {
|
||||
logger.error('Error fetching attachment content', {
|
||||
messageId,
|
||||
attachmentId: attachment.id,
|
||||
error: error instanceof Error ? error.message : String(error),
|
||||
});
|
||||
// Return attachment without content if fetch fails
|
||||
return attachment;
|
||||
}
|
||||
}
|
||||
// Already has contentBytes, return as-is
|
||||
return attachment;
|
||||
})
|
||||
);
|
||||
|
||||
message.attachments = attachmentsWithContent;
|
||||
}
|
||||
|
||||
return message;
|
||||
} catch (error: any) {
|
||||
logger.error('Error fetching email from Microsoft Graph', {
|
||||
mailCredentialIdHash: Buffer.from(mailCredentialId).toString('base64').slice(0, 12),
|
||||
@ -385,3 +424,39 @@ export async function getGraphUnreadCount(
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch a single attachment by ID from a message using Microsoft Graph API
|
||||
*/
|
||||
export async function fetchGraphAttachment(
|
||||
mailCredentialId: string,
|
||||
messageId: string,
|
||||
attachmentId: string
|
||||
): Promise<{
|
||||
id: string;
|
||||
name: string;
|
||||
contentType: string;
|
||||
size: number;
|
||||
contentBytes: string; // Base64 encoded content
|
||||
}> {
|
||||
try {
|
||||
const client = await getMicrosoftGraphClient(mailCredentialId);
|
||||
|
||||
const response = await client.get(`/me/messages/${messageId}/attachments/${attachmentId}`);
|
||||
|
||||
return response.data;
|
||||
} catch (error: any) {
|
||||
logger.error('Error fetching attachment from Microsoft Graph', {
|
||||
mailCredentialIdHash: Buffer.from(mailCredentialId).toString('base64').slice(0, 12),
|
||||
messageId,
|
||||
attachmentId,
|
||||
error: error instanceof Error ? error.message : String(error),
|
||||
});
|
||||
|
||||
if (error.response?.status === 401 || error.response?.status === 403) {
|
||||
throw new Error('Microsoft Graph API access denied - may need to re-authenticate with Mail.Read permissions');
|
||||
}
|
||||
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user