diff --git a/lib/services/caldav-sync.ts b/lib/services/caldav-sync.ts index b31d92d..867ee94 100644 --- a/lib/services/caldav-sync.ts +++ b/lib/services/caldav-sync.ts @@ -26,8 +26,8 @@ export async function getInfomaniakCalDAVClient( email: string, password: string ): Promise { - // Infomaniak CalDAV base URL - const baseUrl = 'https://sync.infomaniak.com/caldav'; + // Infomaniak CalDAV base URL (from Infomaniak sync assistant) + const baseUrl = 'https://sync.infomaniak.com'; const client = createClient(baseUrl, { username: email, @@ -47,52 +47,92 @@ export async function discoverInfomaniakCalendars( try { const client = await getInfomaniakCalDAVClient(email, password); - // List all calendars using PROPFIND - const items = await client.getDirectoryContents('/'); + // Try to discover calendar home set using CalDAV discovery + // First, try to find the calendar home set using current-user-principal + let calendarHomePath = '/calendars/'; - const calendars: CalDAVCalendar[] = []; + // Extract username from email (before @) or use email as username + // Infomaniak might use the email as username or require the Infomaniak username + const username = email.split('@')[0]; - for (const item of items) { - if (item.type === 'directory' && item.filename !== '/') { - // Get calendar properties - try { - const props = await client.customRequest(item.filename, { - method: 'PROPFIND', - headers: { - Depth: '0', - 'Content-Type': 'application/xml', - }, - data: ` + // Try different paths + const possiblePaths = [ + `/calendars/${username}/`, + `/calendars/${email}/`, + '/calendars/', + '/', + ]; + + let calendars: CalDAVCalendar[] = []; + + for (const path of possiblePaths) { + try { + // List all calendars using PROPFIND with Depth: 1 + const items = await client.getDirectoryContents(path); + + for (const item of items) { + if (item.type === 'directory' && item.filename !== '/' && item.filename !== path) { + // Get calendar properties + try { + const props = await client.customRequest(item.filename, { + method: 'PROPFIND', + headers: { + Depth: '0', + 'Content-Type': 'application/xml', + }, + data: ` + `, - }); + }); - // Parse XML response to extract calendar name and color - const displayName = extractDisplayName(props.data); - const color = extractCalendarColor(props.data); + // Check if it's a calendar (has calendar resource type) + const isCalendar = typeof props.data === 'string' && + (props.data.includes(' 0) { + break; + } + } catch (pathError) { + // Try next path + logger.debug(`Path ${path} failed, trying next`, { + error: pathError instanceof Error ? pathError.message : String(pathError), + }); + continue; } } @@ -102,7 +142,9 @@ export async function discoverInfomaniakCalendars( email, error: error instanceof Error ? error.message : String(error), }); - throw error; + // Ne pas faire échouer toute la page agenda si la découverte échoue + // On retourne simplement une liste vide -> pas de sync auto possible + return []; } }