mirror of
https://github.com/teslamate-org/teslamate.git
synced 2026-01-24 21:06:08 +08:00
64 lines
1.8 KiB
Elixir
64 lines
1.8 KiB
Elixir
defmodule TeslaApi.Auth.Refresh do
|
|
import TeslaApi.Auth, only: [post: 2]
|
|
|
|
alias TeslaApi.{Auth, Error}
|
|
|
|
@web_client_id TeslaApi.Auth.web_client_id()
|
|
|
|
def refresh(%Auth{} = auth) do
|
|
issuer_url =
|
|
case derive_issuer_url_from_oat(auth.token) do
|
|
{:ok, issuer_url} ->
|
|
issuer_url
|
|
|
|
:error ->
|
|
case decode_jwt_payload(auth.token) do
|
|
{:ok, %{"iss" => iss}} -> URI.parse(iss)
|
|
_ -> "https://auth.tesla.com/oauth2/v3"
|
|
end
|
|
end
|
|
|
|
data = %{
|
|
grant_type: "refresh_token",
|
|
scope: "openid email offline_access",
|
|
client_id: @web_client_id,
|
|
refresh_token: auth.refresh_token
|
|
}
|
|
|
|
case post("#{issuer_url}/token", data) do
|
|
{:ok, %Tesla.Env{status: 200, body: body}} ->
|
|
auth = %Auth{
|
|
token: body["access_token"],
|
|
type: body["token_type"],
|
|
expires_in: body["expires_in"],
|
|
refresh_token: body["refresh_token"],
|
|
created_at: body["created_at"]
|
|
}
|
|
|
|
{:ok, auth}
|
|
|
|
error ->
|
|
Error.into(error, :token_refresh)
|
|
end
|
|
end
|
|
|
|
defp derive_issuer_url_from_oat("qts-" <> _), do: {:ok, "https://auth.tesla.com/oauth2/v3"}
|
|
defp derive_issuer_url_from_oat("eu-" <> _), do: {:ok, "https://auth.tesla.com/oauth2/v3"}
|
|
defp derive_issuer_url_from_oat("cn-" <> _), do: {:ok, "https://auth.tesla.cn/oauth2/v3"}
|
|
defp derive_issuer_url_from_oat(_), do: :error
|
|
|
|
defp decode_jwt_payload(jwt) do
|
|
with [_algo, payload, _signature] <- String.split(jwt, "."),
|
|
{:ok, payload} <- Base.decode64(payload, padding: false),
|
|
{:ok, payload} <- Jason.decode(payload) do
|
|
{:ok, payload}
|
|
else
|
|
l when is_list(l) ->
|
|
Error.into({:error, :invalid_jwt}, :invalid_access_token)
|
|
|
|
error ->
|
|
Error.into(error, :invalid_access_token)
|
|
end
|
|
end
|
|
end
|