Packages

Typed Elixir client for Kagi Search, Summarizer, and Maps, built on Req.

Current section

Files

Jump to
kagi_ex lib kagi session_token.ex
Raw

lib/kagi/session_token.ex

defmodule Kagi.SessionToken do
@moduledoc false
alias Kagi.Error
# RFC 6265 cookie-octets: printable US-ASCII except whitespace, double
# quotes, commas, semicolons, and backslashes. \A and \z keep a trailing
# newline from slipping past the $ anchor.
@cookie_octets ~r/\A[\x21\x23-\x2B\x2D-\x3A\x3C-\x5B\x5D-\x7E]+\z/
@spec resolve() :: {:ok, String.t()} | {:error, Error.t()}
def resolve do
case normalize_token(Application.get_env(:kagi_ex, :session_token)) do
nil ->
{:error,
Error.new(
:missing_session_token,
"missing session token; configure :kagi_ex, :session_token"
)}
token ->
validate_token(token)
end
end
@spec normalize_token(term()) :: String.t() | nil
defp normalize_token(token) when is_binary(token) do
token = String.trim(token)
if token == "", do: nil, else: token
end
defp normalize_token(_token), do: nil
@spec validate_token(String.t()) :: {:ok, String.t()} | {:error, Error.t()}
defp validate_token(token) do
if Regex.match?(@cookie_octets, token) do
{:ok, token}
else
{:error,
Error.new(
:invalid_session_token,
"session token contains characters not allowed in a cookie value; " <>
"configure only the kagi_session value, not a full Cookie header"
)}
end
end
end