pas-external 3.0.0

Ppoppo Accounts System (PAS) external SDK -- OAuth2 PKCE, PASETO verification, Axum middleware, session liveness
Documentation
use crate::oauth::UserInfo;
use crate::session_liveness::EncryptedRefreshToken;
use crate::types::{PpnumId, UserId};

/// Session data from a successful PAS authentication.
///
/// Passed to [`SessionStore::create`](super::SessionStore::create) for the consumer to persist.
///
/// # Data ownership
///
/// `user_info` is **transient** data from PAS. It should be used for logging or
/// display at login time, but PAS-owned fields (`ppnum`, `email`) must NOT be
/// persisted in the consumer's database. Fetch via PAS userinfo API when needed.
#[derive(Debug, Clone)]
#[non_exhaustive]
pub struct NewSession {
    /// PAS ppnum identifier (OAuth `sub` claim, ULID format).
    pub ppnum_id: PpnumId,
    /// User ID returned by [`AccountResolver::resolve`](super::AccountResolver::resolve).
    pub user_id: UserId,
    /// PAS refresh token for this session, **already encrypted** by the SDK
    /// using the `TokenCipher` supplied to
    /// [`PasAuthConfig::with_refresh_token_cipher`](super::PasAuthConfig::with_refresh_token_cipher).
    ///
    /// `None` iff (a) PAS issued no refresh_token (rare — only for special
    /// scopes), or (b) the consumer did not configure a cipher (DEV_AUTH
    /// flows, or consumers that explicitly opt out of refresh-token
    /// persistence).
    ///
    /// **OAuth consumers (RCW, CTW):** PAS does NOT apply Refresh Token Rotation
    /// (RTR) for OAuth clients — the same token is reused across refreshes.
    /// Lifetime: 180 days of inactivity expiry.
    ///
    /// Store the ciphertext (`as_str()` or `into_inner()`) in your session
    /// table. The plaintext **never** crosses this boundary, so a consumer
    /// schema bug cannot expose it.
    pub refresh_token: Option<EncryptedRefreshToken>,
    /// Client `User-Agent` header value.
    pub user_agent: Option<String>,
    /// Client IP address. See
    /// [`PasAuthConfig::with_xff_trusted_proxies`](super::PasAuthConfig::with_xff_trusted_proxies)
    /// to control the X-Forwarded-For walk for your proxy topology.
    pub ip_address: Option<String>,
    /// PAS UserInfo snapshot (transient — for display, NOT for DB storage).
    pub user_info: UserInfo,
}