Current section
Files
Jump to
Current section
Files
lib/auth/session_token.ex
defmodule Dialup.Auth.SessionToken do
@moduledoc """
Opaque session token generation and hashing.
Raw tokens are sent to clients (cookie). Only SHA-256 hashes are stored in the
database, following the `phx_gen_auth` model.
"""
@session_byte_size 32
@token_contexts %{
session: 60 * 60 * 24 * 60,
confirm: 60 * 60 * 24 * 7,
reset_password: 60 * 60,
change_email: 60 * 60 * 24 * 7
}
@doc "Generates a URL-safe opaque session token."
@spec generate() :: binary()
def generate do
@session_byte_size
|> :crypto.strong_rand_bytes()
|> Base.url_encode64(padding: false)
end
@doc "Returns the TTL in seconds for a token context."
@spec ttl(atom()) :: non_neg_integer()
def ttl(context) when is_atom(context), do: Map.fetch!(@token_contexts, context)
@doc "Hashes a raw token for database storage."
@spec hash(binary()) :: binary()
def hash(token) when is_binary(token) do
:crypto.hash(:sha256, token)
end
@doc "Constant-time comparison of a raw token against a stored hash."
@spec valid?(binary(), binary()) :: boolean()
def valid?(token, stored_hash) when is_binary(token) and is_binary(stored_hash) do
Plug.Crypto.secure_compare(hash(token), stored_hash)
end
end