Teac.OAuth (teac v1.0.0)

Copy Markdown View Source

Token validation and incremental authorization helpers.

Incremental authorization

Rather than requesting every possible scope up front, incremental authorization lets you request only the scopes a user needs for the feature they're about to use. Twitch only shows a consent prompt for scopes not already granted, so repeat visits feel frictionless.

Typical flow

# 1. Validate the user's current token to see what scopes they have.
{:ok, token_info} = Teac.OAuth.validate_token(conn.assigns.current_user_token)

# 2. Declare what a specific feature requires.
required = [Teac.Scopes.Channel.moderate(), Teac.Scopes.User.read_chat()]

# 3. Find what's missing.
missing = Teac.OAuth.missing_scopes(token_info, required)

# 4. If anything is missing, redirect to re-authorize with the full scope list.
#    Twitch won't re-prompt for already-granted scopes, but the resulting
#    token only contains what you explicitly request — so always pass all
#    desired scopes, not just the missing ones.
if missing != [] do
  url = Teac.OAuth.AuthorizationCodeFlow.authorize_url(scope: required)
  redirect(conn, external: url)
end

Summary

Functions

Returns the subset of required_scopes not present in the token.

Validates an OAuth token and returns the scopes it currently grants.

Functions

missing_scopes(token, required)

@spec missing_scopes(Teac.OAuth.TokenInfo.t(), [String.t()]) :: [String.t()]
@spec missing_scopes(String.t(), [String.t()]) ::
  {:ok, [String.t()]} | {:error, :invalid_token | term()}

Returns the subset of required_scopes not present in the token.

Accepts either a %Teac.OAuth.TokenInfo{} (from validate_token/1) or a raw token string. When given a string, calls validate_token/1 internally and returns {:error, reason} if validation fails.

Example

required = [Teac.Scopes.Channel.moderate(), Teac.Scopes.User.read_chat()]

# From a TokenInfo struct (already validated):
[] = Teac.OAuth.missing_scopes(token_info, required)

# From a raw token string:
{:ok, ["channel:moderate"]} = Teac.OAuth.missing_scopes("oauth_token", required)

validate_token(token)

@spec validate_token(String.t()) ::
  {:ok, Teac.OAuth.TokenInfo.t()} | {:error, :invalid_token | term()}

Validates an OAuth token and returns the scopes it currently grants.

Calls Twitch's /oauth2/validate endpoint. Useful for checking which scopes a token has before deciding whether to trigger incremental auth.

Returns {:error, :invalid_token} when the token is expired or invalid.

Example

{:ok, %Teac.OAuth.TokenInfo{scopes: scopes}} = Teac.OAuth.validate_token("oauth_token_string")