43 lines
1.3 KiB
Elixir
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
|