# `HuggingfaceClient.Hub.Enterprise.Oauth`
[🔗](https://github.com/huggingface/huggingface_client/blob/v0.1.0/lib/huggingface_client/hub/enterprise/oauth.ex#L1)

OAuth PKCE flow for "Sign in with HuggingFace".

Implements the full PKCE (Proof Key for Code Exchange) authorization code flow,
mirroring `oauthLoginUrl` and `oauthHandleRedirect` from `@huggingface/hub`.

## Flow

1. Generate a login URL: `HuggingfaceClient.oauth_login_url/1`
2. Redirect the user to that URL
3. The user approves access on HuggingFace
4. They are redirected back to your app with `?code=...&state=...`
5. Call `HuggingfaceClient.oauth_handle_redirect/1` with the code and state

## Example (Phoenix LiveView)

    # Step 1: Generate URL
    {:ok, %{url: login_url, state: state, nonce: nonce}} =
      HuggingfaceClient.oauth_login_url(
        client_id: "my-app-id",
        redirect_uri: "https://myapp.com/auth/callback",
        scopes: "openid profile read-repos"
      )

    # Store state + nonce in session, redirect user to login_url

    # Step 2: Handle callback
    {:ok, result} = HuggingfaceClient.oauth_handle_redirect(
      code:          params["code"],
      state:         params["state"],
      stored_state:  session[:oauth_state],
      nonce:         session[:oauth_nonce],
      client_id:     "my-app-id",
      client_secret: System.get_env("HF_CLIENT_SECRET"),
      redirect_uri:  "https://myapp.com/auth/callback"
    )

    # result.access_token — use for Hub API calls
    # result.user_info    — %{sub:, name:, email:, ...}

# `handle_redirect`

```elixir
@spec handle_redirect(keyword()) :: {:ok, map()} | {:error, Exception.t()}
```

Handles an OAuth redirect callback and exchanges the code for tokens.

Returns `{:ok, %{access_token, expires_at, user_info, scope}}`.

## Required options

- `:code` — the `code` query param from the redirect
- `:state` — the `state` query param from the redirect
- `:stored_state` — the state you generated and stored in session
- `:code_verifier` — the PKCE verifier you stored in session
- `:client_id` — OAuth app client ID
- `:redirect_uri` — must match the original redirect_uri

## Optional

- `:client_secret` — for confidential apps
- `:nonce` — for ID token verification

# `login_url`

```elixir
@spec login_url(keyword()) :: {:ok, map()} | {:error, Exception.t()}
```

Generates an OAuth login URL with PKCE challenge.

Returns `{:ok, %{url: String.t(), state: String.t(), nonce: String.t(), code_verifier: String.t()}}`.

You must persist `state`, `nonce`, and `code_verifier` (e.g. in the session)
for use in `handle_redirect/1`.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
