52 lines
1.5 KiB
Bash
Executable file
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
|
|
"
|