courrier msft oauth

This commit is contained in:
alma 2025-05-02 09:53:17 +02:00
parent 06de428e61
commit ab1f541b53
2 changed files with 49 additions and 58 deletions

View File

@ -260,7 +260,7 @@ export async function getImapConnection(
if (!credentials) {
console.log(`Credentials not found in cache for ${userId}${accountId ? ` account ${accountId}` : ''}, attempting database lookup`);
// Fetch directly from database with all fields
// Fetch directly from database
const dbCredentials = await prisma.mailCredentials.findFirst({
where: {
AND: [
@ -268,7 +268,7 @@ export async function getImapConnection(
accountId ? { id: accountId } : {}
]
}
}) as MailCredentialsWithOAuth | null;
});
if (!dbCredentials) {
console.error(`No credentials found for user ${userId}${accountId ? ` account ${accountId}` : ''}`);
@ -276,49 +276,27 @@ export async function getImapConnection(
throw new Error('Email account credentials not found');
}
// Map database fields to our credential format
if (dbCredentials) {
credentials = {
email: dbCredentials.email,
password: dbCredentials.password || '',
host: dbCredentials.host,
port: dbCredentials.port,
secure: dbCredentials.secure,
smtp_host: dbCredentials.smtp_host || undefined,
smtp_port: dbCredentials.smtp_port || undefined,
smtp_secure: dbCredentials.smtp_secure ?? false,
display_name: dbCredentials.display_name || undefined,
color: dbCredentials.color || undefined,
// Map OAuth fields - using camelCase field names from the schema
useOAuth: dbCredentials.useOAuth || false,
accessToken: dbCredentials.accessToken || undefined,
refreshToken: dbCredentials.refreshToken || undefined,
tokenExpiry: dbCredentials.tokenExpiry ? dbCredentials.tokenExpiry.getTime() : undefined
} as EmailCredentialsExtended; // Cast to extended type
// Log credentials (safely)
console.log('Loaded credentials from database:', {
email: credentials.email,
host: credentials.host,
port: credentials.port,
useOAuth: credentials.useOAuth,
hasAccessToken: !!credentials.accessToken,
hasRefreshToken: !!credentials.refreshToken,
tokenExpiry: credentials.tokenExpiry ? new Date(credentials.tokenExpiry).toISOString() : undefined
});
// Cache the credentials for future use
await cacheEmailCredentials(userId, accountId, credentials);
}
// Create our credentials object from database data
credentials = {
email: dbCredentials.email,
password: dbCredentials.password || '',
host: dbCredentials.host,
port: dbCredentials.port,
secure: dbCredentials.secure,
smtp_host: dbCredentials.smtp_host || undefined,
smtp_port: dbCredentials.smtp_port || undefined,
smtp_secure: dbCredentials.smtp_secure ?? false,
display_name: dbCredentials.display_name || undefined,
color: dbCredentials.color || undefined
};
}
// Cast to extended type
const extendedCreds = credentials as EmailCredentialsExtended;
// If using OAuth, ensure we have a fresh token
// If this account is marked as using OAuth in the cache
if (extendedCreds.useOAuth) {
console.log(`Account is configured to use OAuth: ${extendedCreds.useOAuth}`);
console.log(`Account is configured to use OAuth`);
if (!extendedCreds.accessToken) {
console.error(`OAuth is enabled but no access token for account ${extendedCreds.email}`);
@ -328,7 +306,7 @@ export async function getImapConnection(
console.log(`Ensuring fresh token for OAuth account ${extendedCreds.email}`);
const { accessToken, success } = await ensureFreshToken(userId, extendedCreds.email);
if (success) {
if (success && accessToken) {
extendedCreds.accessToken = accessToken;
console.log(`Successfully refreshed token for ${extendedCreds.email}`);
} else {
@ -548,11 +526,20 @@ export async function saveUserEmailCredentials(
// Cast to extended type to access OAuth properties
const extendedCreds = credentials as EmailCredentialsExtended;
// Store OAuth information in a separate object for caching
const oauthData = {
useOAuth: extendedCreds.useOAuth,
accessToken: extendedCreds.accessToken,
refreshToken: extendedCreds.refreshToken,
tokenExpiry: extendedCreds.tokenExpiry
};
// Extract only the fields that exist in the database schema
// Based on the schema from 'npx prisma db pull', OAuth fields don't exist
const dbCredentials = {
email: credentials.email,
password: credentials.password ?? '',
password: credentials.password ?? '', // Required field in the DB schema
host: credentials.host,
port: credentials.port,
secure: credentials.secure ?? true,
@ -560,21 +547,19 @@ export async function saveUserEmailCredentials(
smtp_port: credentials.smtp_port || null,
smtp_secure: credentials.smtp_secure ?? false,
display_name: credentials.display_name || null,
color: credentials.color || null,
// Add OAuth fields if present - using the camelCase names from the schema
useOAuth: extendedCreds.useOAuth ?? false,
accessToken: extendedCreds.accessToken || null,
refreshToken: extendedCreds.refreshToken || null,
tokenExpiry: extendedCreds.tokenExpiry ? new Date(extendedCreds.tokenExpiry) : null
color: credentials.color || null
};
try {
console.log('Saving credentials with OAuth data:', {
console.log('Saving credentials to database:', {
...dbCredentials,
password: dbCredentials.password ? '***' : null,
accessToken: dbCredentials.accessToken ? '***' : null,
refreshToken: dbCredentials.refreshToken ? '***' : null,
useOAuth: dbCredentials.useOAuth
});
console.log('OAuth data will be saved to Redis cache only:', {
hasOAuth: !!oauthData.useOAuth,
hasAccessToken: !!oauthData.accessToken,
hasRefreshToken: !!oauthData.refreshToken
});
// Save to database using the unique constraint on [userId, email]
@ -597,9 +582,15 @@ export async function saveUserEmailCredentials(
}
});
// Cache the full credentials object in Redis
await cacheEmailCredentials(userId, accountId, extendedCreds);
console.log('Successfully saved and cached credentials for user:', userId);
// Create a combined credentials object for caching
const fullCreds = {
...dbCredentials,
...oauthData
} as EmailCredentialsExtended; // Cast to the expected type
// Cache the full credentials including OAuth tokens
await cacheEmailCredentials(userId, accountId, fullCreds);
console.log('Successfully saved credentials to database and cached full data with OAuth tokens');
} catch (error) {
console.error('Error saving credentials:', error);
throw error;

View File

@ -66,10 +66,10 @@ model MailCredentials {
secure Boolean @default(true)
// OAuth Settings
useOAuth Boolean @default(false)
refreshToken String?
accessToken String?
tokenExpiry DateTime?
use_oauth Boolean @default(false)
refresh_token String?
access_token String?
token_expiry DateTime?
// SMTP Settings
smtp_host String?