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

Defines the storage behavior for persisting authentication data.

Storage is the final stage in KeenAuth's pipeline architecture. It handles
persisting user data, tokens, and session information. Storage implementations
can be as simple as session-based or as sophisticated as multi-layer persistence.

## Pipeline Stage

The storage is the final stage in the authentication flow:

```
Strategy → Mapper → Processor → **Storage**
```

## Flexibility

Storage implementations can vary based on your needs:

- **Session Storage** (default): Simple session-based storage
- **Database Storage**: Persistent user sessions in database
- **JWT Storage**: Stateless authentication with JWT tokens
- **Multi-layer**: Combine database + session + JWT for different purposes

## Example Implementation

    defmodule MyApp.Auth.DatabaseStorage do
      @behaviour KeenAuth.Storage

      def store(conn, provider, user, oauth_response) do
        {:ok, session} = create_user_session(user, provider)
        conn = put_session(conn, :session_id, session.id)
        {:ok, conn}
      end

      def current_user(conn) do
        with session_id when not is_nil(session_id) <- get_session(conn, :session_id),
             session when not is_nil(session) <- get_session_from_db(session_id) do
          session.user
        else
          _ -> nil
        end
      end

      # ... implement other callbacks
    end

## Configuration

Configure a custom storage implementation:

    config :keen_auth,
      storage: MyApp.Auth.CustomStorage

# `authenticated?`

```elixir
@callback authenticated?(conn :: Plug.Conn.t()) :: boolean()
```

# `current_user`

```elixir
@callback current_user(conn :: Plug.Conn.t()) :: any() | nil
```

# `delete`

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

# `get_access_token`

```elixir
@callback get_access_token(conn :: Plug.Conn.t()) :: binary() | nil
```

# `get_id_token`

```elixir
@callback get_id_token(conn :: Plug.Conn.t()) :: binary() | nil
```

# `get_provider`

```elixir
@callback get_provider(conn :: Plug.Conn.t()) :: binary() | nil
```

# `get_refresh_token`

```elixir
@callback get_refresh_token(conn :: Plug.Conn.t()) :: binary() | nil
```

# `put_current_user`

```elixir
@callback put_current_user(
  conn :: Plug.Conn.t(),
  provider :: atom(),
  KeenAuth.User.t() | map()
) ::
  Plug.Conn.t()
```

# `put_provider`

```elixir
@callback put_provider(conn :: Plug.Conn.t(), provider :: atom()) :: Plug.Conn.t()
```

# `put_tokens`

```elixir
@callback put_tokens(
  conn :: Plug.Conn.t(),
  provider :: atom(),
  KeenAuth.AuthenticationController.tokens_map()
) :: Plug.Conn.t()
```

# `store`

```elixir
@callback store(
  conn :: Plug.Conn.t(),
  provider :: atom(),
  mapped_user :: KeenAuth.User.t() | map(),
  oauth_response ::
    KeenAuth.AuthenticationController.oauth_callback_response() | nil
) :: {:ok, Plug.Conn.t()}
```

# `authenticated?`

# `current_storage`

# `current_user`

# `delete`

# `get_access_token`

# `get_id_token`

# `get_provider`

# `get_refresh_token`

# `get_storage`

# `put_current_user`

# `put_provider`

# `put_tokens`

# `store`

---

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