Checkpoint: OAuth2 IMAP pour Office 365 : ajout du mode d'authentification OAuth2 pour l'import email (Azure AD Client Credentials), sélecteur basic/oauth2 dans l'UI, bouton "Tester la connexion IMAP", procédure testEmailConnection dans le router. Migration DB emailImportAuthMode appliquée.

This commit is contained in:
Manus
2026-06-05 05:54:21 -04:00
parent 22515e5414
commit 4ef130f21d
9 changed files with 2256 additions and 17 deletions

View File

@@ -82,7 +82,7 @@ import { extractInvoicesWithMistral, generateMetadataJSON } from "./invoiceExtra
import { localStoragePut, generateStorageKey } from "./localStorage";
import { testSftpConnection, exportInvoiceToSftp, getUserSftpConfig } from "./sftpExport";
import { drawBapCartouche } from "./bapCartouche";
import { startEmailImportService, stopEmailImportService, isEmailImportServiceRunning, triggerEmailCheck } from "./emailImportService";
import { startEmailImportService, stopEmailImportService, isEmailImportServiceRunning, triggerEmailCheck, testImapConnection } from "./emailImportService";
import { startFolderImportService, stopFolderImportService, isFolderImportServiceRunning } from "./folderImportService";
import { TRPCError } from "@trpc/server";
@@ -1567,6 +1567,7 @@ export const appRouter = router({
emailImportPort: z.number().min(1).max(65535).optional(),
emailImportFrequency: z.number().min(1).optional(),
emailImportSinceDate: z.number().nullable().optional(), // Unix timestamp (s)
emailImportAuthMode: z.enum(["basic", "oauth2"]).optional(),
exportFolder: z.string().nullable().optional(),
exportFolderType: z.enum(["local", "teams", "sharepoint"]).optional(),
bapExportMode: z.enum(["browser", "folder", "both"]).optional(),
@@ -1635,6 +1636,37 @@ export const appRouter = router({
}
}),
testEmailConnection: protectedProcedure
.mutation(async ({ ctx }) => {
const settings = await getImportSettingsByUser(ctx.user.id);
if (!settings?.emailImportAddress || !settings?.emailImportHost) {
return { success: false, message: 'Configuration IMAP incomplète (adresse email ou serveur IMAP manquant)' };
}
const authMode = (settings as any).emailImportAuthMode as 'basic' | 'oauth2' || 'basic';
if (authMode === 'basic' && !settings.emailImportPassword) {
return { success: false, message: 'Mot de passe IMAP manquant' };
}
if (authMode === 'oauth2' && (!settings.azureTenantId || !settings.azureClientId || !settings.azureClientSecret)) {
return { success: false, message: 'Credentials Azure AD incomplets pour OAuth2 (Tenant ID, Client ID, Client Secret requis)' };
}
const result = await testImapConnection({
userId: ctx.user.id,
emailAddress: settings.emailImportAddress,
password: settings.emailImportPassword || '',
host: settings.emailImportHost,
port: settings.emailImportPort || 993,
authMode,
azureTenantId: settings.azureTenantId || undefined,
azureClientId: settings.azureClientId || undefined,
azureClientSecret: settings.azureClientSecret || undefined,
});
return result;
}),
testSharePointUpload: protectedProcedure
.mutation(async ({ ctx }) => {
const settings = await getImportSettingsByUser(ctx.user.id);