runScheduledSync was hardcoded to the Gmail OAuth path, so every
scheduled tick for an IMAP account in config.toml failed with the
misleading 'oauth2: token expired and refresh token is not set'
error. Look up the source by identifier or display_name and
dispatch: Gmail keeps the existing incremental-sync flow; IMAP
runs a full sync via the shared buildAPIClient helper. A nil
source still falls back to Gmail to preserve the token-first
workflow.
- findScheduledSyncSource matches against identifier OR
display_name. IMAP sources from add-imap store the user-facing
email in display_name while identifier is the imaps:// URL, so
a config.toml entry like email = "user@example.com" resolves
the IMAP row instead of falling back to Gmail.
- runScheduledIMAPSync passes src.DisplayName (the email recorded
by add-imap) to confirmDefaultIdentity, not src.Identifier (the
imaps:// URL), so the daemon never injects a URL into
account_identities if the user has cleared identities. A
legacy IMAP row with NULL display_name silently skips the
write.
Fixes kenn-io#329
Summary
runScheduledSyncwas hardcoded to the Gmail OAuth path, so every scheduled tick for an IMAP account configured inconfig.tomlfailed with the misleadingoauth2: token expired and refresh token is not seterror and no IMAP sync ever ran from the daemon.source_type: Gmail keeps the existing incremental flow (and its daemon-specific token error messages); IMAP runs a full sync via the sharedbuildAPIClienthelper (NoResume=true, matching the CLI's IMAP behaviour).nilsource still falls back to Gmail to preserve the token-first workflow where tokens are uploaded via the API before any source row exists.Notes
buildAPIClienthelper handles both password-IMAP (viaimap.LoadCredentials) and OAuth-IMAP (Microsoft) — both work from the daemon.Test plan
go vet ./...cleanmake test— full suite greenTestFindScheduledSyncSource— covers nil / imap-only / mixed gmail+mbox / mbox-only identifier rows.TestRunScheduledIMAPSync_NoCredentials— verifies the dispatcher actually reaches the IMAP path (no Gmail-flavoured error) and fails with a useful credentials error.