Skip to content

Commit

Permalink
Merge pull request #159 from s0er3n/main
Browse files Browse the repository at this point in the history
feat: add twitch strategy
  • Loading branch information
danschultzer authored Dec 26, 2024
2 parents 6dce181 + 6212ebb commit 418eb93
Show file tree
Hide file tree
Showing 4 changed files with 88 additions and 0 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
* `Assent.Strategy.OAuth2` `:state` override in `:authorization_parms` has been deprecated
* `Assent.Strategy.OIDC` now supports `none` authentication method
* `Assent.Strategy.Bitbucket` added
* `Assent.Strategy.Twitch` added

## v0.2.10 (2024-04-11)

Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ Multi-provider authentication framework.
* Strava - `Assent.Strategy.Strava`
* Slack - `Assent.Strategy.Slack`
* Stripe Connect - `Assent.Strategy.Stripe`
* Twitch - `Assent.Strategy.Twitch`
* Twitter - `Assent.Strategy.Twitter`
* VK - `Assent.Strategy.VK`

Expand Down
24 changes: 24 additions & 0 deletions lib/assent/strategies/twitch.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
defmodule Assent.Strategy.Twitch do
@moduledoc """
Twitch OpenID Connect strategy.
See `Assent.Strategy.OIDC` for more.
"""
use Assent.Strategy.OIDC.Base

@impl true
def default_config(_config) do
[
base_url: "https://id.twitch.tv/oauth2",
authorization_params: [
scope: "user:read:email",
# Only sub is in the ID Token by default so we must specify the
# additional claims:
# https://dev.twitch.tv/docs/authentication/getting-tokens-oidc/#requesting-claims
claims:
"{\"id_token\":{\"email\":null,\"email_verified\":null,\"picture\":null,\"preferred_username\":null}}"
],
client_authentication_method: "client_secret_post"
]
end
end
62 changes: 62 additions & 0 deletions test/assent/strategies/twitch_test.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
defmodule Assent.Strategy.TwitchTest do
use Assent.Test.OIDCTestCase

alias Assent.Strategy.Twitch

# From https://dev.twitch.tv/docs/authentication/getting-tokens-oidc/#oidc-authorization-code-grant-flow
@id_token_claims %{
"iss" => "https://id.twitch.tv/oauth2",
"sub" => "713936733",
"aud" => "hof5gwx0su6owfnys0nyan9c87zr6t",
"exp" => :os.system_time(:second) + 60,
"iat" => :os.system_time(:second),
"email" => "[email protected]",
"email_verified" => true,
"picture" => "https://justin.tv/picture.png",
"preferred_username" => "scotwht"
}
@user %{
"email" => "[email protected]",
"email_verified" => true,
"sub" => "713936733",
"picture" => "https://justin.tv/picture.png",
"preferred_username" => "scotwht"
}

test "authorize_url/2", %{config: config} do
assert {:ok, %{url: url}} = Twitch.authorize_url(config)

url = URI.parse(url)

assert url.path == "/oauth/authorize"

assert %{"client_id" => "id", "scope" => scope, "claims" => claims} =
URI.decode_query(url.query)

assert scope =~ "user:read:email"

assert @json_library.decode!(claims)["id_token"] == %{
"email" => nil,
"email_verified" => nil,
"picture" => nil,
"preferred_username" => nil
}
end

test "callback/2", %{config: config, callback_params: params} do
openid_config =
Map.put(config[:openid_configuration], "issuer", "https://id.twitch.tv/oauth2")

config =
Keyword.merge(config,
openid_configuration: openid_config,
client_id: "hof5gwx0su6owfnys0nyan9c87zr6t"
)

[key | _rest] = expect_oidc_jwks_uri_request()
expect_oidc_access_token_request(id_token_opts: [claims: @id_token_claims, kid: key["kid"]])

assert {:ok, %{user: user}} = Twitch.callback(config, params)
assert user == @user
end
end

0 comments on commit 418eb93

Please sign in to comment.