///|
const AUTH_PROVIDER_GITHUB_COPILOT = "github_copilot"
///|
const AUTH_PROVIDER_CODEX_OAUTH = "codex_oauth"
///|
pub fn managed_auth_default_provider() -> String {
AUTH_PROVIDER_CODEX_OAUTH
}
///|
fn managed_auth_provider_supported(provider : String) -> Bool {
provider == AUTH_PROVIDER_GITHUB_COPILOT ||
provider == AUTH_PROVIDER_CODEX_OAUTH
}
///|
fn managed_auth_provider_error(provider : String) -> String {
"Unsupported auth provider: \{provider}"
}
///|
fn managed_auth_account_login(credentials : @codex.Credentials) -> String {
@codex.extract_token_claims(credentials.idToken).email catch {
_ => credentials.accountId
}
}
///|
fn managed_auth_account_json(
provider : String,
credentials : @codex.Credentials,
is_default? : Bool = true,
) -> Json {
{
"id": Json::string(credentials.accountId),
"provider": Json::string(provider),
"login": Json::string(managed_auth_account_login(credentials)),
"avatar_url": Json::null(),
"authenticated_at": Json::number(0.0),
"is_default": Json::boolean(is_default),
"github_domain": Json::string(
if provider == AUTH_PROVIDER_CODEX_OAUTH {
"chatgpt.com"
} else {
"github.com"
},
),
}.to_json()
}
///|
fn managed_auth_status_json(
provider : String,
credentials : @codex.Credentials?,
migration_error? : String,
) -> Json {
let accounts = match credentials {
Some(credentials) =>
[managed_auth_account_json(provider, credentials, is_default=true)]
None => []
}
{
"provider": Json::string(provider),
"authenticated": Json::boolean(credentials is Some(_)),
"default_account_id": match credentials {
Some(credentials) => Json::string(credentials.accountId)
None => Json::null()
},
"migration_error": match migration_error {
Some(error) => Json::string(error)
None => Json::null()
},
"accounts": Json::array(accounts),
}.to_json()
}
///|
async fn managed_auth_codex_credentials() -> @codex.Credentials? {
try @codex.load_credentials() catch {
_ => None
} noraise {
credentials => Some(credentials)
}
}
///|
pub async fn managed_auth_get_status(provider : String) -> Result[Json, String] {
if !managed_auth_provider_supported(provider) {
return Err(managed_auth_provider_error(provider))
}
if provider == AUTH_PROVIDER_GITHUB_COPILOT {
return Ok(copilot_get_auth_status())
}
Ok(managed_auth_status_json(provider, managed_auth_codex_credentials()))
}
///|
pub async fn managed_auth_list_accounts(
provider : String,
) -> Result[Json, String] {
if !managed_auth_provider_supported(provider) {
return Err(managed_auth_provider_error(provider))
}
if provider == AUTH_PROVIDER_GITHUB_COPILOT {
return Ok(copilot_list_accounts())
}
match managed_auth_codex_credentials() {
Some(credentials) =>
Ok(
Json::array([
managed_auth_account_json(provider, credentials, is_default=true),
]),
)
None => Ok(Json::array([]))
}
}
///|
pub async fn managed_auth_logout(provider : String) -> Result[Json, String] {
if !managed_auth_provider_supported(provider) {
return Err(managed_auth_provider_error(provider))
}
if provider == AUTH_PROVIDER_GITHUB_COPILOT {
return Ok(copilot_logout())
}
@codex.delete_credentials()
Ok(Json::null())
}
///|
pub async fn managed_auth_remove_account(
provider : String,
account_id : String,
) -> Result[Json, String] {
if !managed_auth_provider_supported(provider) {
return Err(managed_auth_provider_error(provider))
}
if provider == AUTH_PROVIDER_GITHUB_COPILOT {
return copilot_remove_account(account_id)
}
match managed_auth_codex_credentials() {
Some(credentials) if credentials.accountId == account_id => {
@codex.delete_credentials()
Ok(Json::null())
}
Some(_) => Err("Account not found: \{account_id}")
None => Err("Account not found: \{account_id}")
}
}
///|
pub async fn managed_auth_set_default_account(
provider : String,
account_id : String,
) -> Result[Json, String] {
if !managed_auth_provider_supported(provider) {
return Err(managed_auth_provider_error(provider))
}
if provider == AUTH_PROVIDER_GITHUB_COPILOT {
return copilot_set_default_account(account_id)
}
match managed_auth_codex_credentials() {
Some(credentials) if credentials.accountId == account_id => Ok(Json::null())
Some(_) => Err("Account not found: \{account_id}")
None => Err("Account not found: \{account_id}")
}
}
///|
pub async fn managed_auth_start_login(
provider : String,
github_domain? : String? = None,
) -> Result[Json, String] {
if !managed_auth_provider_supported(provider) {
return Err(managed_auth_provider_error(provider))
}
if provider == AUTH_PROVIDER_GITHUB_COPILOT {
return copilot_start_device_flow(github_domain)
}
Ok(@codex.start_device_flow().to_json()) catch {
error => Err("\{error}")
}
}
///|
pub async fn managed_auth_poll_for_account(
provider : String,
device_code : String,
user_code : String?,
github_domain? : String? = None,
) -> Result[Json?, String] {
if !managed_auth_provider_supported(provider) {
return Err(managed_auth_provider_error(provider))
}
if provider == AUTH_PROVIDER_GITHUB_COPILOT {
return copilot_poll_for_account(device_code, github_domain)
}
guard user_code is Some(user_code) else { return Err("missing_user_code") }
try {
match @codex.poll_device_flow(device_code, user_code) {
Some(credentials) =>
Ok(
Some(
managed_auth_account_json(provider, credentials, is_default=true),
),
)
None => Ok(None)
}
} catch {
error => Err("\{error}")
}
}