towerops/lib/mix/tasks/totp_time_check.exs
2026-01-28 17:02:36 -06:00

75 lines
2.5 KiB
Elixir

defmodule Mix.Tasks.Totp.TimeCheck do
@shortdoc "Check server time and TOTP time synchronization"
@moduledoc """
Diagnostic tool to check if the server's clock is correct.
Usage:
mix totp.time_check
This will:
1. Show the server's current time (BEAM VM time)
2. Show the system's current time
3. Calculate what TOTP codes should be valid right now for a test secret
"""
use Mix.Task
require Logger
def run(_args) do
Mix.Task.run("app.start")
IO.puts("\n=== Time Synchronization Check ===\n")
# Get different time sources
system_time = System.system_time(:second)
os_time = :os.system_time(:second)
datetime_now = DateTime.utc_now()
IO.puts("System.system_time(:second): #{system_time}")
IO.puts("#{DateTime.from_unix!(system_time)}")
IO.puts("")
IO.puts(":os.system_time(:second): #{os_time}")
IO.puts("#{DateTime.from_unix!(os_time)}")
IO.puts("")
IO.puts("DateTime.utc_now(): #{datetime_now}")
IO.puts(" → unix: #{DateTime.to_unix(datetime_now)}")
IO.puts("")
# Check if they match
if system_time == os_time and system_time == DateTime.to_unix(datetime_now) do
IO.puts("✓ All time sources agree")
else
IO.puts("⚠️ WARNING: Time sources disagree!")
IO.puts(" System vs OS diff: #{system_time - os_time} seconds")
IO.puts(" System vs DateTime diff: #{system_time - DateTime.to_unix(datetime_now)} seconds")
end
IO.puts("")
# Show what TOTP codes would be generated now
test_secret = NimbleTOTP.secret()
current_code = NimbleTOTP.verification_code(test_secret, time: system_time)
prev_code = NimbleTOTP.verification_code(test_secret, time: system_time - 30)
next_code = NimbleTOTP.verification_code(test_secret, time: system_time + 30)
IO.puts("Test TOTP codes (with random secret):")
IO.puts(" Current window: #{current_code}")
IO.puts(" Previous (-30s): #{prev_code}")
IO.puts(" Next (+30s): #{next_code}")
IO.puts("")
# Recommend action
IO.puts("=== Recommendations ===")
IO.puts("")
IO.puts("Compare the server time above with actual UTC time:")
IO.puts(" Current actual UTC: Run 'date -u' on your local machine")
IO.puts("")
IO.puts("If the server time is wrong:")
IO.puts(" 1. Check K8s node time: kubectl exec -it <pod> -- date -u")
IO.puts(" 2. Check if NTP is running on the node")
IO.puts(" 3. Restart the pod to resync time")
IO.puts("")
end
end