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
@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)
@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")