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