fix(dkv): search msgfolderroot for EWS subfolder resolution
Tessera CI/CD / Lint & Type Check (push) Successful in 43s
Tessera CI/CD / Tests (push) Successful in 47s
Tessera CI/CD / Build & Publish Images (push) Successful in 24s

FindFolder was searching only under inbox DistinguishedFolderId, missing
folders at mailbox root level. Now searches msgfolderroot (full mailbox)
so custom folders like DKV are found regardless of placement.

Also adds HTTP status check and debug logging for FindFolder responses.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-06-30 10:23:30 +02:00
parent 30eb40c184
commit dcba4b9977
@@ -276,7 +276,8 @@ export class ExchangeInboxProvider implements InboxProvider {
/** Resolve folder config to a EWS ParentFolderIds XML element. /** Resolve folder config to a EWS ParentFolderIds XML element.
* Well-known names → <t:DistinguishedFolderId>. * Well-known names → <t:DistinguishedFolderId>.
* Custom names (e.g. "DKV" or "INBOX/DKV") → FindFolder deep search under inbox → <t:FolderId>. * Custom names (e.g. "DKV" or "INBOX/DKV") → FindFolder deep search under msgfolderroot → <t:FolderId>.
* Searches msgfolderroot (full mailbox) so folders at root level are found, not just inbox subfolders.
*/ */
private async resolveFolderElement(config: InboxConfig): Promise<string> { private async resolveFolderElement(config: InboxConfig): Promise<string> {
const folderCfg = config.folder ?? 'INBOX'; const folderCfg = config.folder ?? 'INBOX';
@@ -286,14 +287,20 @@ export class ExchangeInboxProvider implements InboxProvider {
if (distinguished) { if (distinguished) {
return `<t:DistinguishedFolderId Id="${escapeXml(distinguished)}"/>`; return `<t:DistinguishedFolderId Id="${escapeXml(distinguished)}"/>`;
} }
// Custom subfolder: resolve via FindFolder // Custom subfolder: search entire mailbox (msgfolderroot) so top-level folders are found too
const ffSoap = findFolderSoap('inbox', displayName); const ffSoap = findFolderSoap('msgfolderroot', displayName);
const ffRes = await this.ewsPost(config, ffSoap, 'FindFolder'); const ffRes = await this.ewsPost(config, ffSoap, 'FindFolder');
const folderId = extractAttr(ffRes.body, 't:FolderId', 'Id'); if (ffRes.statusCode !== 200) {
if (!folderId) { this.logger.warn(`EWS FindFolder HTTP ${ffRes.statusCode} for "${displayName}" — falling back to inbox`);
this.logger.warn(`EWS FindFolder: subfolder "${displayName}" not found — falling back to inbox`);
return `<t:DistinguishedFolderId Id="inbox"/>`; return `<t:DistinguishedFolderId Id="inbox"/>`;
} }
this.logger.debug(`EWS FindFolder response for "${displayName}": ${ffRes.body.slice(0, 500)}`);
const folderId = extractAttr(ffRes.body, 't:FolderId', 'Id');
if (!folderId) {
this.logger.warn(`EWS FindFolder: subfolder "${displayName}" not found under msgfolderroot — falling back to inbox`);
return `<t:DistinguishedFolderId Id="inbox"/>`;
}
this.logger.log(`EWS FindFolder: resolved "${displayName}" → FolderId ${folderId.slice(0, 20)}…`);
return `<t:FolderId Id="${escapeXml(folderId)}"/>`; return `<t:FolderId Id="${escapeXml(folderId)}"/>`;
} }