Skip to content

Commit

Permalink
Merge pull request #1 from SalesLoft/SL-36345
Browse files Browse the repository at this point in the history
[SL-36345] Add regional twr header to access token
  • Loading branch information
danny-rosenblatt-salesloft authored May 17, 2022
2 parents 00276cb + a4b152b commit 2fcc99b
Show file tree
Hide file tree
Showing 2 changed files with 66 additions and 13 deletions.
33 changes: 23 additions & 10 deletions lib/ex_twilio/jwt/access_token.ex
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,17 @@ defmodule ExTwilio.JWT.AccessToken do
api_secret: nil,
identity: nil,
grants: [],
expires_in: nil
expires_in: nil,
region: nil

@type t :: %__MODULE__{
account_sid: String.t(),
api_key: String.t(),
api_secret: String.t(),
identity: String.t(),
grants: [ExTwilio.JWT.Grant.t()],
expires_in: integer
expires_in: integer,
region: String.t()
}

@doc """
Expand All @@ -39,7 +41,8 @@ defmodule ExTwilio.JWT.AccessToken do
api_secret: "secret",
identity: "[email protected]",
expires_in: 86_400,
grants: [AccessToken.ChatGrant.new(service_sid: "sid")]
grants: [AccessToken.ChatGrant.new(service_sid: "sid")],
region: 'us1'
)
"""
Expand All @@ -62,7 +65,8 @@ defmodule ExTwilio.JWT.AccessToken do
api_secret: "secret",
identity: "[email protected]",
expires_in: 86_400,
grants: [AccessToken.ChatGrant.new(service_sid: "sid")]
grants: [AccessToken.ChatGrant.new(service_sid: "sid")],
region: 'us1'
)
AccessToken.to_jwt!(token)
Expand Down Expand Up @@ -90,12 +94,7 @@ defmodule ExTwilio.JWT.AccessToken do
|> add_claim("exp", fn -> (DateTime.utc_now() |> DateTime.to_unix()) + token.expires_in end)
|> add_claim("iat", fn -> DateTime.utc_now() |> DateTime.to_unix() end)

signer =
Joken.Signer.create("HS256", token.api_secret, %{
"typ" => "JWT",
"alg" => "HS256",
"cty" => "twilio-fpa;v=1"
})
signer = Joken.Signer.create("HS256", token.api_secret, headers(token))

Joken.generate_and_sign!(token_config, %{}, signer)
end
Expand All @@ -115,6 +114,20 @@ defmodule ExTwilio.JWT.AccessToken do
grants
end

defp headers(%__MODULE__{region: region}) when is_binary(region) do
Map.put(base_headers(), "twr", region)
end

defp headers(_token), do: base_headers()

defp base_headers do
%{
"typ" => "JWT",
"alg" => "HS256",
"cty" => "twilio-fpa;v=1"
}
end

defp random_str do
16
|> :crypto.strong_rand_bytes()
Expand Down
46 changes: 43 additions & 3 deletions test/ex_twilio/jwt/access_token_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ defmodule ExTwilio.JWT.AccessTokenTest do
AccessToken.ChatGrant.new(service_sid: "sid"),
AccessToken.VideoGrant.new(room: "room")
],
expires_in: 86_400
expires_in: 86_400,
region: "region"
) == %AccessToken{
token_identifier: "id",
account_sid: "sid",
Expand All @@ -26,7 +27,8 @@ defmodule ExTwilio.JWT.AccessTokenTest do
%AccessToken.ChatGrant{service_sid: "sid"},
%AccessToken.VideoGrant{room: "room"}
],
expires_in: 86_400
expires_in: 86_400,
region: "region"
}
end
end
Expand All @@ -47,7 +49,8 @@ defmodule ExTwilio.JWT.AccessTokenTest do
outgoing_application_params: %{key: "value"}
)
],
expires_in: 86_400
expires_in: 86_400,
region: "region"
)
|> AccessToken.to_jwt!()

Expand All @@ -70,6 +73,43 @@ defmodule ExTwilio.JWT.AccessTokenTest do
}
end

test "signs Twilio JWT with region header when present" do
token =
AccessToken.new(
token_identifier: "id",
account_sid: "sid",
api_key: "sid",
api_secret: "secret",
identity: "[email protected]",
grants: [AccessToken.ChatGrant.new(service_sid: "sid")],
expires_in: 86_400,
region: "us1"
)
|> AccessToken.to_jwt!()

{:ok, headers} = Joken.peek_header(token)

assert headers["twr"] == "us1"
end

test "does not include region header in Twilio JWT in when not provided" do
token =
AccessToken.new(
token_identifier: "id",
account_sid: "sid",
api_key: "sid",
api_secret: "secret",
identity: "[email protected]",
grants: [AccessToken.ChatGrant.new(service_sid: "sid")],
expires_in: 86_400
)
|> AccessToken.to_jwt!()

{:ok, headers} = Joken.peek_header(token)

assert_raise KeyError, fn -> Map.fetch!(headers, "twr") end
end

test "validates binary keys" do
for invalid <- [123, 'sid', nil, false],
field <- [:account_sid, :api_key, :api_secret, :identity] do
Expand Down

0 comments on commit 2fcc99b

Please sign in to comment.