Skip to main content

codex_oauth/
lib.rs

1//! PKCE OAuth login for OpenAI Codex.
2//!
3//! Thin wrapper around [`motosan_ai_oauth`] with the Codex provider pre-configured.
4//!
5//! # Usage
6//!
7//! ```no_run
8//! #[tokio::main]
9//! async fn main() -> Result<(), codex_oauth::Error> {
10//!     let token = codex_oauth::login().await?;
11//!     println!("{}", token.access_token);
12//!     Ok(())
13//! }
14//! ```
15//!
16//! # Notes
17//!
18//! - Requires port 1455 to be free on localhost (hardcoded by OpenAI's app registration).
19//! - `CLIENT_ID` is hardcoded to OpenAI's public Codex app registration and is not configurable.
20
21pub use motosan_ai_oauth::{Error, Token};
22
23/// Open a browser-based PKCE login flow and return the resulting OAuth token.
24pub async fn login() -> Result<Token, Error> {
25    motosan_ai_oauth::login(&motosan_ai_oauth::providers::codex::codex()).await
26}
27
28/// Exchange a stored refresh token for a new [`Token`].
29pub async fn refresh(refresh_token: &str) -> Result<Token, Error> {
30    motosan_ai_oauth::refresh(&motosan_ai_oauth::providers::codex::codex(), refresh_token).await
31}
32
33#[cfg(test)]
34mod tests {
35    use super::*;
36
37    #[test]
38    fn re_exports_compile() {
39        let _: fn() -> bool = || {
40            let t = Token {
41                access_token: String::new(),
42                refresh_token: String::new(),
43                id_token: None,
44                expires_in: 0,
45                issued_at: 0,
46            };
47            t.is_expired()
48        };
49    }
50}