58 lines
1.2 KiB
Elixir
58 lines
1.2 KiB
Elixir
defmodule TuskerPush.Apns.Token do
|
|
use GenServer
|
|
|
|
require Logger
|
|
|
|
def start_link(_) do
|
|
GenServer.start_link(__MODULE__, nil, name: __MODULE__)
|
|
end
|
|
|
|
def current do
|
|
GenServer.call(__MODULE__, :current)
|
|
end
|
|
|
|
@impl true
|
|
def init(_) do
|
|
Logger.debug("Apns.Token initialized, scheduling update")
|
|
Process.send_after(self(), :refresh, 1000 * 60 * 45)
|
|
{:ok, generate_token()}
|
|
end
|
|
|
|
@impl true
|
|
def handle_info(:refresh, _old_token) do
|
|
Logger.debug("Apns.Token regenerated")
|
|
Process.send_after(self(), :refresh, 1000 * 60 * 45)
|
|
{:noreply, generate_token()}
|
|
end
|
|
|
|
@impl true
|
|
def handle_call(:current, _from, token) do
|
|
{:reply, token, token}
|
|
end
|
|
|
|
defp generate_token do
|
|
# can't use Joken because it always inserts "typ": "JWT" which APNS doesn't like
|
|
|
|
config = Application.fetch_env!(:tusker_push, :apns)
|
|
|
|
jwk = JOSE.JWK.from_pem(config[:key_pem])
|
|
|
|
jws =
|
|
JOSE.JWS.from_map(%{
|
|
"kid" => config[:key_id],
|
|
"alg" => "ES256"
|
|
})
|
|
|
|
claims = %{
|
|
"iss" => config[:team_id],
|
|
"iat" => DateTime.utc_now() |> DateTime.to_unix()
|
|
}
|
|
|
|
{_, result} =
|
|
JOSE.JWT.sign(jwk, jws, claims)
|
|
|> JOSE.JWS.compact()
|
|
|
|
result
|
|
end
|
|
end
|