mail page imap connection mime 5 bis rest 16 login page 5
This commit is contained in:
parent
76ea7ffe66
commit
a9221f2d65
@ -83,6 +83,43 @@ interface ImapError extends Error {
|
|||||||
source?: string;
|
source?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface Email {
|
||||||
|
id: string;
|
||||||
|
from: string;
|
||||||
|
subject: string;
|
||||||
|
date: string;
|
||||||
|
body: string;
|
||||||
|
read: boolean;
|
||||||
|
starred: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface EmailHeaders {
|
||||||
|
from: string;
|
||||||
|
subject: string;
|
||||||
|
date: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
function parseEmailHeaders(buffer: string): EmailHeaders {
|
||||||
|
const headers: EmailHeaders = {
|
||||||
|
from: '',
|
||||||
|
subject: '',
|
||||||
|
date: ''
|
||||||
|
};
|
||||||
|
|
||||||
|
const lines = buffer.split('\r\n');
|
||||||
|
for (const line of lines) {
|
||||||
|
if (line.toLowerCase().startsWith('from:')) {
|
||||||
|
headers.from = line.substring(5).trim();
|
||||||
|
} else if (line.toLowerCase().startsWith('subject:')) {
|
||||||
|
headers.subject = line.substring(8).trim();
|
||||||
|
} else if (line.toLowerCase().startsWith('date:')) {
|
||||||
|
headers.date = line.substring(5).trim();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return headers;
|
||||||
|
}
|
||||||
|
|
||||||
// Helper function to create a promise-based IMAP connection
|
// Helper function to create a promise-based IMAP connection
|
||||||
function createImapConnection(imapConfig: Imap.Config) {
|
function createImapConnection(imapConfig: Imap.Config) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
@ -191,11 +228,27 @@ function fetchMessages(imap: Imap, box: string): Promise<ImapMessage[]> {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function GET(request: Request) {
|
export async function GET() {
|
||||||
|
console.log('Starting email fetch process...');
|
||||||
|
|
||||||
try {
|
try {
|
||||||
console.log('Starting email fetch process...');
|
const credentials = getStoredCredentials();
|
||||||
|
if (!credentials) {
|
||||||
const imapConfig = getImapConfig();
|
return NextResponse.json(
|
||||||
|
{ error: 'No credentials found', details: 'Please login first' },
|
||||||
|
{ status: 401 }
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const imapConfig = {
|
||||||
|
user: credentials.email,
|
||||||
|
password: credentials.password,
|
||||||
|
host: credentials.host,
|
||||||
|
port: credentials.port,
|
||||||
|
tls: true,
|
||||||
|
debug: console.log
|
||||||
|
};
|
||||||
|
|
||||||
console.log('IMAP Configuration:', {
|
console.log('IMAP Configuration:', {
|
||||||
user: imapConfig.user,
|
user: imapConfig.user,
|
||||||
host: imapConfig.host,
|
host: imapConfig.host,
|
||||||
@ -204,38 +257,105 @@ export async function GET(request: Request) {
|
|||||||
hasPassword: !!imapConfig.password
|
hasPassword: !!imapConfig.password
|
||||||
});
|
});
|
||||||
|
|
||||||
console.log('Creating IMAP connection...');
|
const imap = new Imap(imapConfig);
|
||||||
const imap = await createImapConnection(imapConfig) as Imap;
|
|
||||||
|
|
||||||
console.log('Fetching messages...');
|
return new Promise((resolve, reject) => {
|
||||||
const messages = await fetchMessages(imap, 'INBOX');
|
imap.once('ready', () => {
|
||||||
|
console.log('IMAP connection ready');
|
||||||
console.log(`Successfully fetched ${messages.length} messages`);
|
imap.openBox('INBOX', false, (err, box) => {
|
||||||
|
if (err) {
|
||||||
// Process messages into the format expected by the frontend
|
console.error('Error opening inbox:', err);
|
||||||
const processedMessages = messages.map((msg: ImapMessage, index: number) => ({
|
imap.end();
|
||||||
id: index + 1,
|
reject(new Error('Failed to open inbox'));
|
||||||
accountId: 1,
|
return;
|
||||||
from: msg.header.from?.[0] || '',
|
}
|
||||||
fromName: (msg.header.from?.[0] || '').split('<')[0].trim(),
|
|
||||||
to: msg.header.to?.[0] || '',
|
|
||||||
subject: msg.header.subject?.[0] || '',
|
|
||||||
body: msg.body || '',
|
|
||||||
date: msg.header.date?.[0] || new Date().toISOString(),
|
|
||||||
read: !(msg.attributes.flags.indexOf('\\Seen') < 0),
|
|
||||||
starred: !(msg.attributes.flags.indexOf('\\Flagged') < 0),
|
|
||||||
category: 'inbox'
|
|
||||||
}));
|
|
||||||
|
|
||||||
imap.end();
|
const fetch = imap.seq.fetch('1:10', {
|
||||||
return NextResponse.json({ messages: processedMessages });
|
bodies: ['HEADER', 'TEXT'],
|
||||||
|
struct: true
|
||||||
|
});
|
||||||
|
|
||||||
|
const messages: Email[] = [];
|
||||||
|
|
||||||
|
fetch.on('message', (msg) => {
|
||||||
|
const email: Email = {
|
||||||
|
id: '',
|
||||||
|
from: '',
|
||||||
|
subject: '',
|
||||||
|
date: '',
|
||||||
|
body: '',
|
||||||
|
read: false,
|
||||||
|
starred: false
|
||||||
|
};
|
||||||
|
|
||||||
|
msg.on('body', (stream) => {
|
||||||
|
let buffer = '';
|
||||||
|
stream.on('data', (chunk) => {
|
||||||
|
buffer += chunk.toString('utf8');
|
||||||
|
});
|
||||||
|
stream.on('end', () => {
|
||||||
|
const headers = parseEmailHeaders(buffer);
|
||||||
|
email.from = headers.from;
|
||||||
|
email.subject = headers.subject;
|
||||||
|
email.date = headers.date;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
msg.once('attributes', (attrs) => {
|
||||||
|
email.id = attrs.uid.toString();
|
||||||
|
email.read = !attrs.flags.includes('\\Unseen');
|
||||||
|
email.starred = attrs.flags.includes('\\Flagged');
|
||||||
|
});
|
||||||
|
|
||||||
|
msg.once('end', () => {
|
||||||
|
messages.push(email);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
fetch.once('error', (err) => {
|
||||||
|
console.error('Fetch error:', err);
|
||||||
|
imap.end();
|
||||||
|
reject(new Error('Failed to fetch messages'));
|
||||||
|
});
|
||||||
|
|
||||||
|
fetch.once('end', () => {
|
||||||
|
imap.end();
|
||||||
|
resolve(NextResponse.json(messages));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
imap.once('error', (err: ImapError) => {
|
||||||
|
console.error('IMAP connection error:', err);
|
||||||
|
console.error('Error details:', {
|
||||||
|
type: err.type,
|
||||||
|
textCode: err.textCode,
|
||||||
|
source: err.source
|
||||||
|
});
|
||||||
|
imap.end();
|
||||||
|
reject(new Error(err.message));
|
||||||
|
});
|
||||||
|
|
||||||
|
imap.connect();
|
||||||
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error in GET handler:', error);
|
console.error('Error in GET handler:', error);
|
||||||
return NextResponse.json({
|
if (error instanceof Error) {
|
||||||
error: 'Failed to fetch emails',
|
if (error.message.includes('Invalid login or password')) {
|
||||||
details: error instanceof Error ? error.message : 'Unknown error'
|
return NextResponse.json(
|
||||||
}, { status: 500 });
|
{ error: 'Invalid login or password', details: error.message },
|
||||||
|
{ status: 401 }
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return NextResponse.json(
|
||||||
|
{ error: 'Failed to fetch emails', details: error.message },
|
||||||
|
{ status: 500 }
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return NextResponse.json(
|
||||||
|
{ error: 'Unknown error occurred' },
|
||||||
|
{ status: 500 }
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -435,7 +435,14 @@ export default function MailPage() {
|
|||||||
try {
|
try {
|
||||||
const response = await fetch('/api/mail');
|
const response = await fetch('/api/mail');
|
||||||
if (!response.ok) {
|
if (!response.ok) {
|
||||||
throw new Error('Failed to fetch emails');
|
const errorData = await response.json();
|
||||||
|
if (errorData.error === 'Invalid login or password') {
|
||||||
|
// Clear invalid credentials and redirect to login
|
||||||
|
localStorage.removeItem('imapCredentials');
|
||||||
|
router.push('/mail/login');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
throw new Error(errorData.details || 'Failed to fetch emails');
|
||||||
}
|
}
|
||||||
const data = await response.json();
|
const data = await response.json();
|
||||||
console.log('API Response:', data); // Debug log
|
console.log('API Response:', data); // Debug log
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user