//! Pure OAuth entities — no HTTP or persistence logic. //! //! # Components //! //! - [`OAuthToken`] — access token with optional refresh token, epoch expiry //! - [`OAuthConfig`] — provider configuration (auth URL, token URL, client id, //! optional client secret, scopes) use serde::{Deserialize, Serialize}; /// An OAuth 2.0 access token with optional refresh token and absolute /// expiry time (epoch seconds). #[derive(Debug, Clone, Serialize, Deserialize)] pub struct OAuthToken { /// The OAuth 2.0 access token string. pub access_token: String, /// Optional refresh token for long-lived access. pub refresh_token: Option, /// Absolute expiry timestamp (epoch seconds since UNIX_EPOCH). pub expires_at: u64, /// Token type, e.g. `"Bearer"`. pub token_type: String, } /// Static configuration for an OAuth provider. #[derive(Debug, Clone, Serialize, Deserialize)] pub struct OAuthConfig { /// Authorization endpoint URL. pub auth_url: String, /// Token exchange endpoint URL. pub token_url: String, /// OAuth client identifier. pub client_id: String, /// Optional client secret (not all flows require it). pub client_secret: Option, /// Space-separated list of requested scopes. pub scopes: Vec, } impl Default for OAuthConfig { fn default() -> Self { OAuthConfig { auth_url: String::new(), token_url: String::new(), client_id: String::new(), client_secret: None, scopes: vec![ "openid".to_string(), "profile".to_string(), "email".to_string(), ], } } }