43 lines
1.3 KiB
Elixir

defmodule MessageServer.Auth do
@spec generate_auth_token(String.t()) :: String.t()
def generate_auth_token(server_id) do
timestamp = System.system_time(:second)
payload = "#{server_id}:#{timestamp}"
signature = :crypto.mac(:hmac, :sha256, get_shared_secret(), payload) |> Base.encode64()
"#{payload}:#{signature}"
end
@spec verify_auth_token(String.t()) :: {:ok, String.t()} | {:error, String.t()}
def verify_auth_token(token) do
case String.split(token, ":") do
[server_id, timestamp_str, signature] ->
payload = "#{server_id}:#{timestamp_str}"
expected_signature =
:crypto.mac(:hmac, :sha256, get_shared_secret(), payload) |> Base.encode64()
timestamp = String.to_integer(timestamp_str)
current_time = System.system_time(:second)
cond do
signature != expected_signature ->
{:error, :auth_failure, "Invalid signature"}
# 5 minute window
current_time - timestamp > 300 ->
{:error, :auth_failure, "Token expired"}
true ->
{:ok, server_id}
end
_ ->
{:error, :auth_failure, "Invalid token format"}
end
end
def get_shared_secret do
System.get_env("AUTH_KEY", "default-secret")
end
end