PlaidEx.OAuth.StateStore (plaid_ex v1.0.0)

Copy Markdown View Source

ETS-backed store for OAuth state parameters.

Stores OAuth state → PKCE verifier mappings with TTL. State is consumed (deleted) on retrieval to prevent replay.

Security properties

  • State is a cryptographically random 32-byte token
  • Each state can only be consumed once (deleted on read)
  • States expire after 10 minutes (configurable)
  • The store is per-node — for multi-node deployments, use a shared cache (Redis) backed by a custom implementation

Summary

Functions

Returns a specification to start this module under a supervisor.

Retrieves and consumes an OAuth state.

Peeks at a state without consuming it. Useful for multi-step flows where the state is needed across redirects.

Stores an OAuth state with optional PKCE verifier. Returns the state token.

Functions

child_spec(init_arg)

Returns a specification to start this module under a supervisor.

See Supervisor.

consume(state)

@spec consume(String.t()) :: {:ok, map()} | {:error, :not_found | :expired}

Retrieves and consumes an OAuth state.

Returns {:ok, metadata} and deletes the state (one-time use). Returns {:error, :not_found} if expired or never existed.

peek(state)

@spec peek(String.t()) :: {:ok, map()} | {:error, :not_found | :expired}

Peeks at a state without consuming it. Useful for multi-step flows where the state is needed across redirects.

put(metadata \\ %{})

@spec put(map()) :: String.t()

Stores an OAuth state with optional PKCE verifier. Returns the state token.

Example

pkce = PlaidEx.OAuth.PKCE.generate()
state = PlaidEx.OAuth.StateStore.put(%{
  pkce: pkce,
  tenant_id: "acme_corp",
  redirect_uri: "https://myapp.com/oauth/callback"
})

start_link(opts \\ [])

@spec start_link(keyword()) :: GenServer.on_start()