towerops/diagnose_totp_secret.sh
2026-01-28 17:18:23 -06:00

52 lines
1.5 KiB
Bash
Executable file

#!/bin/bash
# Diagnose TOTP secret for a specific user
if [ -z "$1" ]; then
echo "Usage: ./diagnose_totp_secret.sh <user_email>"
exit 1
fi
USER_EMAIL="$1"
echo "=== TOTP Secret Diagnostic ==="
echo "User: $USER_EMAIL"
echo ""
kubectl exec -n towerops deployment/towerops -- bin/towerops rpc "
alias Towerops.Accounts
require Logger
user = Accounts.get_user_by_email(\"$USER_EMAIL\")
if is_nil(user) do
IO.puts(\"❌ User not found\")
else
IO.puts(\"✓ User found: #{user.email}\")
if is_nil(user.totp_secret) do
IO.puts(\"❌ TOTP not enabled for this user\")
else
IO.puts(\"✓ TOTP enabled\")
IO.puts(\"Secret length: #{byte_size(user.totp_secret)} bytes\")
# Check if secret is valid Base32
try do
# NimbleTOTP expects the secret to be base32-encoded
# Let's generate a code to verify the secret is valid
current_time = System.system_time(:second)
code = NimbleTOTP.verification_code(user.totp_secret, time: current_time)
IO.puts(\"✓ Secret is valid (can generate codes)\")
IO.puts(\"\")
IO.puts(\"Current expected codes:\")
IO.puts(\" Current: #{code}\")
IO.puts(\" Prev (-30s): #{NimbleTOTP.verification_code(user.totp_secret, time: current_time - 30)}\")
IO.puts(\" Next (+30s): #{NimbleTOTP.verification_code(user.totp_secret, time: current_time + 30)}\")
IO.puts(\"\")
IO.puts(\"Server time: #{DateTime.from_unix!(current_time)}\")
rescue
e -> IO.puts(\"❌ Secret is INVALID: #{inspect(e)}\")
end
end
end
"