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