//! Microsoft/Outlook OAuth2 provider. //! //! Implements OAuth2 for Outlook/Microsoft 365 access via IMAP with XOAUTH2. //! Uses default trait implementations for token exchange. //! //! See: https://docs.microsoft.com/en-us/azure/active-directory/develop/v2-oauth2-auth-code-flow use crate::oauth::provider::{OAuthProvider, OAuthProviderConfig}; /// Microsoft/Outlook OAuth2 provider. /// /// Uses PKCE for desktop apps (client secret is optional). pub struct MicrosoftProvider { client_id: String, client_secret: Option, config: OAuthProviderConfig, } impl MicrosoftProvider { /// Creates a new Microsoft OAuth provider. /// /// # Arguments /// * `client_id` - Azure AD application (client) ID /// * `client_secret` - Optional Azure AD client secret (desktop apps use PKCE instead) pub fn new(client_id: impl Into, client_secret: Option) -> Self { Self { client_id: client_id.into(), client_secret, config: OAuthProviderConfig { auth_url: "https://login.microsoftonline.com/common/oauth2/v2.0/authorize".to_string(), token_url: "https://login.microsoftonline.com/common/oauth2/v2.0/token".to_string(), scopes: vec![ "https://outlook.office.com/IMAP.AccessAsUser.All".to_string(), "https://outlook.office.com/SMTP.Send".to_string(), "offline_access".to_string(), "openid".to_string(), "email".to_string(), "profile".to_string(), ], uses_jmap: false, jmap_session_url: None, imap_server: Some("outlook.office365.com".to_string()), imap_port: Some(993), smtp_server: Some("smtp.office365.com".to_string()), smtp_port: Some(587), userinfo_url: Some("https://graph.microsoft.com/v1.0/me".to_string()), email_json_path: vec!["mail", "userPrincipalName"], // Try mail first, then UPN }, } } } impl OAuthProvider for MicrosoftProvider { fn id(&self) -> &'static str { "microsoft" } fn display_name(&self) -> &'static str { "Microsoft / Outlook" } fn config(&self) -> &OAuthProviderConfig { &self.config } fn client_id(&self) -> &str { &self.client_id } fn client_secret(&self) -> Option<&str> { self.client_secret.as_deref() } fn customize_auth_url(&self, url: &mut String) { // Microsoft-specific: response_mode for better security url.push_str("&response_mode=query"); } // Uses default exchange_code, refresh_token, get_user_email implementations }