47 lines
1.2 KiB
Elixir
47 lines
1.2 KiB
Elixir
|
|
defmodule ShootingEventPhx.Auth.SessionStore do
|
||
|
|
@moduledoc false
|
||
|
|
use Agent
|
||
|
|
|
||
|
|
@duration_seconds 8 * 60 * 60
|
||
|
|
|
||
|
|
def start_link(_opts) do
|
||
|
|
Agent.start_link(fn -> %{} end, name: __MODULE__)
|
||
|
|
end
|
||
|
|
|
||
|
|
def create_token do
|
||
|
|
token = :crypto.strong_rand_bytes(32) |> Base.encode16(case: :lower)
|
||
|
|
expires_at = DateTime.add(DateTime.utc_now(), @duration_seconds, :second)
|
||
|
|
Agent.update(__MODULE__, &Map.put(&1, token, expires_at))
|
||
|
|
{:ok, token, expires_at}
|
||
|
|
end
|
||
|
|
|
||
|
|
def validate_token(token) when is_binary(token) do
|
||
|
|
purge_expired()
|
||
|
|
|
||
|
|
Agent.get(__MODULE__, fn tokens ->
|
||
|
|
case Map.get(tokens, token) do
|
||
|
|
%DateTime{} = expires_at -> DateTime.compare(DateTime.utc_now(), expires_at) == :lt
|
||
|
|
_ -> false
|
||
|
|
end
|
||
|
|
end)
|
||
|
|
end
|
||
|
|
|
||
|
|
def delete_token(token) when is_binary(token) do
|
||
|
|
Agent.update(__MODULE__, &Map.delete(&1, token))
|
||
|
|
end
|
||
|
|
|
||
|
|
def purge_expired do
|
||
|
|
now = DateTime.utc_now()
|
||
|
|
|
||
|
|
Agent.update(__MODULE__, fn tokens ->
|
||
|
|
Enum.reduce(tokens, %{}, fn {token, expires_at}, acc ->
|
||
|
|
if DateTime.compare(now, expires_at) == :lt do
|
||
|
|
Map.put(acc, token, expires_at)
|
||
|
|
else
|
||
|
|
acc
|
||
|
|
end
|
||
|
|
end)
|
||
|
|
end)
|
||
|
|
end
|
||
|
|
end
|