//! Fastmail OAuth2 provider. //! //! Implements OAuth2 with PKCE for Fastmail's JMAP API access. //! Uses ClientIdOnly (no client secret required with PKCE). //! //! See: https://www.fastmail.com/developer/integrating-with-fastmail/ use crate::oauth::provider::{ClientAuthMethod, OAuthProvider, OAuthProviderConfig}; /// Fastmail OAuth2 provider. /// /// Uses PKCE with client_id only (no secret required). /// Uses JMAP instead of IMAP. pub struct FastmailProvider { client_id: String, config: OAuthProviderConfig, } impl FastmailProvider { /// Creates a new Fastmail OAuth provider. pub fn new(client_id: impl Into) -> Self { Self { client_id: client_id.into(), config: OAuthProviderConfig { auth_url: "https://api.fastmail.com/oauth/authorize".to_string(), token_url: "https://api.fastmail.com/oauth/refresh".to_string(), scopes: vec![ "urn:ietf:params:jmap:core".to_string(), "urn:ietf:params:jmap:mail".to_string(), "urn:ietf:params:jmap:submission".to_string(), ], uses_jmap: true, jmap_session_url: Some("https://api.fastmail.com/jmap/session".to_string()), imap_server: None, imap_port: None, smtp_server: None, smtp_port: None, userinfo_url: Some("https://api.fastmail.com/jmap/session".to_string()), email_json_path: vec!["username"], // Fastmail uses "username" for email }, } } } impl OAuthProvider for FastmailProvider { fn id(&self) -> &'static str { "fastmail" } fn display_name(&self) -> &'static str { "Fastmail" } fn config(&self) -> &OAuthProviderConfig { &self.config } fn client_id(&self) -> &str { &self.client_id } fn client_auth_method(&self) -> ClientAuthMethod { // Fastmail uses PKCE, no client secret needed ClientAuthMethod::ClientIdOnly } // Uses default exchange_code, refresh_token, get_user_email implementations }