# `KeenAuth.AuthenticationController`
[🔗](https://github.com/KeenMate/keen_auth/blob/main/lib/authentication_controller.ex#L1)

Handles the OAuth authentication flow for KeenAuth.

This controller provides the core endpoints for OAuth authentication:
- `new/2` - Initiates the OAuth flow by redirecting to the provider
- `callback/2` - Handles the OAuth callback from the provider
- `delete/2` - Signs out the user

## Usage

You can use this controller directly via `KeenAuth.authentication_routes/0` or create
your own controller that uses this module:

    defmodule MyAppWeb.AuthController do
      use KeenAuth.AuthenticationController

      # Override any callback as needed
      def callback(conn, params) do
        # Custom logic before
        result = super(conn, params)
        # Custom logic after
        result
      end
    end

## Authentication Flow

1. User visits `/auth/:provider/new`
2. Controller redirects to OAuth provider with authorization URL
3. Provider redirects back to `/auth/:provider/callback`
4. Controller processes the callback through the pipeline:
   - **Strategy** fetches user data from provider
   - **Mapper** normalizes the user data
   - **Processor** handles business logic (validation, database, etc.)
   - **Storage** persists the session
5. User is redirected to the original destination

# `oauth_callback_response`

```elixir
@type oauth_callback_response() :: %{
  user: KeenAuth.User.t() | map(),
  token: tokens_map()
}
```

# `tokens_map`

```elixir
@type tokens_map() :: %{
  optional(:access_token) =&gt; binary(),
  optional(:id_token) =&gt; binary(),
  optional(:refresh_token) =&gt; binary()
}
```

# `callback`

```elixir
@callback callback(conn :: Plug.Conn.t(), any()) :: Plug.Conn.t()
```

# `delete`

```elixir
@callback delete(conn :: Plug.Conn.t(), any()) :: Plug.Conn.t()
```

# `new`

```elixir
@callback new(conn :: Plug.Conn.t(), any()) :: Plug.Conn.t()
```

# `callback`

Handles the OAuth callback from the provider.

Processes the authentication response through the full pipeline:
1. Validates the OAuth callback and fetches user data
2. Maps the raw user data to a normalized format
3. Processes the user through custom business logic
4. Stores the authentication in the configured storage

On success, redirects the user to their original destination.

# `delete`

Signs out the user by delegating to the processor's `sign_out/3` callback.

If a provider is specified in params, uses that provider. Otherwise,
retrieves the provider from storage. Redirects back if no user is signed in.

# `get_authorization_uri`

```elixir
@spec get_authorization_uri(Plug.Conn.t(), atom()) ::
  {:ok, %{session_params: map(), url: binary()}}
```

# `make_callback_back`

```elixir
@spec make_callback_back(Plug.Conn.t(), atom(), map(), map()) ::
  {:ok, oauth_callback_response()}
```

# `map_user`

```elixir
@spec map_user(Plug.Conn.t(), atom(), map()) :: KeenAuth.User.t()
```

# `maybe_put_redirect_to`

```elixir
@spec maybe_put_redirect_to(Plug.Conn.t(), map()) :: Plug.Conn.t()
```

# `new`

Initiates the OAuth flow by redirecting to the provider's authorization URL.

Stores session parameters and optional redirect URL, then redirects the user
to the OAuth provider for authentication.

# `process`

```elixir
@spec process(Plug.Conn.t(), atom(), KeenAuth.User.t() | map(), any()) :: any()
```

# `store`

```elixir
@spec store(
  Plug.Conn.t(),
  atom(),
  KeenAuth.User.t() | map(),
  oauth_callback_response()
) :: any()
```

---

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