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}