courrier multi account

This commit is contained in:
alma 2025-04-27 16:14:50 +02:00
parent 7eb6dd5b81
commit b66f1adb3a
2 changed files with 61 additions and 49 deletions

View File

@ -96,6 +96,11 @@ interface EmailCredentials {
port: number;
secure?: boolean;
encryptedPassword?: string;
smtp_host?: string;
smtp_port?: number;
smtp_secure?: boolean;
display_name?: string;
color?: string;
}
interface ImapSessionData {
@ -129,7 +134,13 @@ export async function cacheEmailCredentials(
email: credentials.email,
host: credentials.host,
port: credentials.port,
secure: credentials.secure ?? true
secure: credentials.secure ?? true,
// Include the extended fields
...(credentials.smtp_host && { smtp_host: credentials.smtp_host }),
...(credentials.smtp_port && { smtp_port: credentials.smtp_port }),
...(credentials.smtp_secure !== undefined && { smtp_secure: credentials.smtp_secure }),
...(credentials.display_name && { display_name: credentials.display_name }),
...(credentials.color && { color: credentials.color })
};
// Encrypt password
@ -156,49 +167,50 @@ export async function cacheEmailCredentials(
}
/**
* Get cached email credentials from Redis
* Get email credentials from Redis
*/
export async function getCachedEmailCredentials(
userId: string
): Promise<EmailCredentials | null> {
export async function getEmailCredentials(userId: string): Promise<EmailCredentials | null> {
const redis = getRedisClient();
const key = KEYS.CREDENTIALS(userId);
try {
const cachedData = await redis.get(key);
if (!cachedData) {
console.log(`No cached credentials found for user ${userId}`);
const credStr = await redis.get(key);
if (!credStr) {
return null;
}
console.log(`Found cached credentials for user ${userId}, attempting to decrypt`);
const credentials = JSON.parse(cachedData) as EmailCredentials;
const creds = JSON.parse(credStr) as EmailCredentials;
// Check if we have encrypted password
if (!credentials.encryptedPassword) {
console.warn(`Cached credentials for user ${userId} missing encrypted password`);
if (!creds.encryptedPassword) {
console.warn(`No encrypted password found for user ${userId}`);
return null;
}
try {
// Decrypt password with error handling
credentials.password = decryptData(credentials.encryptedPassword);
delete credentials.encryptedPassword;
// Decrypt the password
const password = decryptData(creds.encryptedPassword);
// Validate the credentials to ensure they're complete
if (!credentials.password || !credentials.email || !credentials.host) {
console.warn(`Incomplete credentials in cache for user ${userId}, missing required fields`);
return null;
}
console.log(`Successfully retrieved and decrypted credentials for ${userId}`);
return credentials;
// Return the full credentials with decrypted password
return {
email: creds.email,
password,
host: creds.host,
port: creds.port,
secure: creds.secure ?? true,
// Include the extended fields if they exist in the cache
...(creds.smtp_host && { smtp_host: creds.smtp_host }),
...(creds.smtp_port && { smtp_port: creds.smtp_port }),
...(creds.smtp_secure !== undefined && { smtp_secure: creds.smtp_secure }),
...(creds.display_name && { display_name: creds.display_name }),
...(creds.color && { color: creds.color })
};
} catch (decryptError) {
console.error(`Failed to decrypt password for user ${userId}:`, decryptError);
return null;
}
} catch (error) {
console.error(`Error retrieving credentials from Redis for user ${userId}:`, error);
console.error(`Error retrieving credentials for user ${userId}:`, error);
return null;
}
}
@ -397,4 +409,14 @@ export async function invalidateUserEmailCache(
}
} while (cursor !== '0');
}
}
/**
* Get cached email credentials from Redis
* @deprecated Use getEmailCredentials instead
*/
export async function getCachedEmailCredentials(
userId: string
): Promise<EmailCredentials | null> {
return getEmailCredentials(userId);
}

View File

@ -192,37 +192,27 @@ export async function saveUserEmailCredentials(
userId: string,
credentials: EmailCredentials
): Promise<void> {
// Save to database
console.log('Saving credentials for user:', userId);
// Extract only the fields that exist in the database schema
const dbCredentials = {
email: credentials.email,
password: credentials.password ?? '',
host: credentials.host,
port: credentials.port
};
// Save to database - only using fields that exist in the schema
await prisma.mailCredentials.upsert({
where: { userId },
update: {
email: credentials.email,
password: credentials.password,
host: credentials.host,
port: credentials.port,
secure: credentials.secure ?? true,
smtp_host: credentials.smtp_host,
smtp_port: credentials.smtp_port,
smtp_secure: credentials.smtp_secure,
display_name: credentials.display_name,
color: credentials.color
},
update: dbCredentials,
create: {
userId,
email: credentials.email,
password: credentials.password,
host: credentials.host,
port: credentials.port,
secure: credentials.secure ?? true,
smtp_host: credentials.smtp_host,
smtp_port: credentials.smtp_port,
smtp_secure: credentials.smtp_secure,
display_name: credentials.display_name,
color: credentials.color
...dbCredentials
}
});
// Also cache in Redis
// Cache the full credentials object in Redis (with all fields)
await cacheEmailCredentials(userId, credentials);
}