Current section
Files
Jump to
Current section
Files
lib/codex/auth.ex
defmodule Codex.Auth do
@moduledoc false
@spec codex_home() :: String.t()
def codex_home do
System.get_env("CODEX_HOME") || Path.join(System.user_home!(), ".codex")
end
@spec auth_paths() :: [String.t()]
def auth_paths do
codex_home = codex_home()
base_paths = [
Path.join(codex_home, "auth.json"),
Path.join(codex_home, ".credentials.json")
]
if System.get_env("CODEX_HOME") do
base_paths
else
(base_paths ++
[
Path.join(System.user_home!(), ".config/codex/credentials.json"),
Path.join(System.user_home!(), ".config/openai/codex.json"),
Path.join(System.user_home!(), ".codex/credentials.json")
])
|> Enum.uniq()
end
end
@spec infer_auth_mode() :: :api | :chatgpt
def infer_auth_mode do
if api_key_env?() || openai_api_key_from_auth() do
:api
else
:chatgpt
end
end
@spec api_key() :: String.t() | nil
def api_key do
api_key_env() || openai_api_key_from_auth()
end
@spec chatgpt_access_token() :: String.t() | nil
def chatgpt_access_token do
auth_paths()
|> Enum.find_value(&read_chatgpt_access_token/1)
end
defp api_key_env? do
case api_key_env() do
value when is_binary(value) and value != "" -> true
_ -> false
end
end
defp api_key_env do
System.get_env("CODEX_API_KEY")
|> normalize_string()
end
defp openai_api_key_from_auth do
auth_paths()
|> Enum.find_value(&read_openai_api_key/1)
end
defp read_openai_api_key(path) do
case read_auth_json(path) do
%{} = decoded -> extract_openai_api_key(decoded)
_ -> nil
end
end
defp read_chatgpt_access_token(path) do
case read_auth_json(path) do
%{} = decoded -> extract_chatgpt_access_token(decoded)
_ -> nil
end
end
defp read_auth_json(path) do
with true <- File.exists?(path),
{:ok, contents} <- File.read(path),
{:ok, decoded} <- Jason.decode(contents) do
decoded
else
_ -> nil
end
end
defp extract_openai_api_key(%{"OPENAI_API_KEY" => key}) when is_binary(key) and key != "" do
String.trim(key)
end
defp extract_openai_api_key(%{"openai_api_key" => key}) when is_binary(key) and key != "" do
String.trim(key)
end
defp extract_openai_api_key(_), do: nil
defp extract_chatgpt_access_token(%{"tokens" => %{"access_token" => token}})
when is_binary(token) and token != "" do
String.trim(token)
end
defp extract_chatgpt_access_token(%{"tokens" => %{"token" => token}})
when is_binary(token) and token != "" do
String.trim(token)
end
defp extract_chatgpt_access_token(%{"access_token" => token})
when is_binary(token) and token != "" do
String.trim(token)
end
defp extract_chatgpt_access_token(%{"token" => token}) when is_binary(token) and token != "" do
String.trim(token)
end
defp extract_chatgpt_access_token(_), do: nil
defp normalize_string(nil), do: nil
defp normalize_string(value) when is_binary(value) do
value = String.trim(value)
if value == "", do: nil, else: value
end
end