feat(email): add MicrosoftGraphProvider (Outlook/365 via Graph OAuth)
b2 of the multi-provider email roadmap. Mirrors the Gmail provider's shape end-to-end so the two stay structurally interchangeable: - MicrosoftGraphConnection model + table (reconciler pattern, SQLite+MySQL, same shape as GmailConnection: encrypted refresh/access token, sync state). - MicrosoftGraphOAuthService: auth-code + offline-access flow against login.microsoftonline.com, encrypted token storage via IDataProtector, message search/thread/detail fetch against Microsoft Graph (conversationId stands in for Gmail's threadId), attachment listing. - MicrosoftGraphProvider implements IEmailProvider — no contract changes; the existing seam was already provider-neutral. - MicrosoftGraphController: connect-url/oauth/callback/status/disconnect, mirrors GmailController's OAuth surface exactly (including the popup postMessage handshake). Job-matching/review endpoints stay Gmail-only for now, per the roadmap — generalising those needs the frontend provider picker work, not this slice. - Registered in DI + IEmailProviderRegistry (multi-registration of IEmailProvider, resolved by ProviderKey). - Config: Microsoft:ClientId/ClientSecret/TenantId/RedirectUri, wired through docker-compose.yml + .env.example alongside the existing Google:Gmail* keys. - Tests: MicrosoftGraphControllerTests (OAuth lifecycle) + MicrosoftGraphProviderTests (DTO mapping onto the neutral contract). 147/147 green (135 existing + 12 new). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -18,6 +18,7 @@ namespace JobTrackerApi.Data
|
||||
public DbSet<Correspondence> Correspondences => Set<Correspondence>();
|
||||
public DbSet<GmailConnection> GmailConnections => Set<GmailConnection>();
|
||||
public DbSet<GmailReviewDecision> GmailReviewDecisions => Set<GmailReviewDecision>();
|
||||
public DbSet<MicrosoftGraphConnection> MicrosoftGraphConnections => Set<MicrosoftGraphConnection>();
|
||||
public DbSet<Attachment> Attachments => Set<Attachment>();
|
||||
public DbSet<RuleSettings> RuleSettings => Set<RuleSettings>();
|
||||
public DbSet<UserRuleSettings> UserRuleSettings => Set<UserRuleSettings>();
|
||||
|
||||
Reference in New Issue
Block a user