mirror of
https://codeberg.org/PostERG/xamxam.git
synced 2026-09-25 01:53:03 +02:00
diag: invalid_grant is SSO auth-method mismatch, not bad creds
- feat: creds-test.sh gum probe for SMTP vs PeerTube auth + PeerTubeService::probeAuth() - feat: app-token.sh gum probe for long-lived PeerTube app token (client_credentials) - docs: add copy-paste proof commands to demonstrate the SSO break to admins
This commit is contained in:
Executable
+139
@@ -0,0 +1,139 @@
|
||||
#!/usr/bin/env bash
|
||||
# =============================================================================
|
||||
# creds-test.sh — gum-powered interactive probe of the credentials shared by
|
||||
# SMTP and PeerTube in the xamxam database.
|
||||
#
|
||||
# Probes two endpoints with the SAME stored username/password, going directly
|
||||
# (bypassing any SSO portal):
|
||||
# • SMTP — TCP connect + SMTP AUTH + disconnect (no mail sent)
|
||||
# • PeerTube — OAuth2 "password" grant against <instance>/api/v1/users/token
|
||||
#
|
||||
# Every run is appended to a log without the plaintext password.
|
||||
#
|
||||
# Usage:
|
||||
# scripts/creds-test.sh [--db <path>] [--instance <url>] [--channel <handle>]
|
||||
# --instance / --channel override the stored values for the PeerTube probe
|
||||
# --show-pwd reveal the decrypted password (interactive confirm)
|
||||
#
|
||||
# Exit code 0 => both probes succeeded; 1 => at least one failed.
|
||||
# =============================================================================
|
||||
set -uo pipefail
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
REPO_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
|
||||
PROBE="$SCRIPT_DIR/creds-probe.php"
|
||||
LOG="$SCRIPT_DIR/../creds-test.log"
|
||||
|
||||
DB_PATH=""
|
||||
INSTANCE=""
|
||||
CHANNEL=""
|
||||
SHOW_PWD=0
|
||||
|
||||
# ---- argument parsing --------------------------------------------------------
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case "$1" in
|
||||
--db) DB_PATH="$2"; shift 2 ;;
|
||||
--instance) INSTANCE="$2"; shift 2 ;;
|
||||
--channel) CHANNEL="$2"; shift 2 ;;
|
||||
--show-pwd) SHOW_PWD=1; shift ;;
|
||||
-h|--help)
|
||||
gum style "Usage:" --bold
|
||||
gum style " scripts/creds-test.sh [--db <path>] [--instance <url>] [--channel <handle>] [--show-pwd]"
|
||||
exit 0 ;;
|
||||
*) echo "Unknown arg: $1" >&2; exit 2 ;;
|
||||
esac
|
||||
done
|
||||
|
||||
# ---- preflight ---------------------------------------------------------------
|
||||
command -v gum >/dev/null || { echo "gum is required (install via 'brew install gum' or the repo justfile)"; exit 2; }
|
||||
command -v php >/dev/null || { echo "php is required"; exit 2; }
|
||||
[[ -f "$PROBE" ]] || { echo "Missing helper: $PROBE"; exit 2; }
|
||||
|
||||
gum style "── XAMXAM · probe SMTP vs PeerTube ────────────────────────" \
|
||||
--border double --padding "1 2" --foreground 212
|
||||
|
||||
# Default DB path: same layout as the PHP helpers.
|
||||
DB_PATH="${DB_PATH:-$REPO_ROOT/app/storage/xamxam.db}"
|
||||
if [[ ! -f "$DB_PATH" ]]; then
|
||||
gum style "✗ Database not found: $DB_PATH" --foreground 196
|
||||
exit 2
|
||||
fi
|
||||
|
||||
PROBE_ARGS=(--db "$DB_PATH")
|
||||
[[ -n "$INSTANCE" ]] && PROBE_ARGS+=(--instance "$INSTANCE")
|
||||
[[ -n "$CHANNEL" ]] && PROBE_ARGS+=(--channel "$CHANNEL")
|
||||
if [[ "$SHOW_PWD" -eq 1 ]]; then
|
||||
# Interactive confirmation BEFORE we ever print a password.
|
||||
if gum confirm "Show the decrypted password on screen? (it will NOT be logged)"; then
|
||||
PROBE_ARGS+=(--with-pwd)
|
||||
else
|
||||
exit 130
|
||||
fi
|
||||
fi
|
||||
|
||||
# ---- run the probe ---------------------------------------------------------------
|
||||
OUT="$(gum spin --spinner minidot --title "Probing SMTP + PeerTube …" \
|
||||
-- php "$PROBE" "${PROBE_ARGS[@]}" 2>/tmp/creds-probe.err)"
|
||||
RC=$?
|
||||
if [[ -n "${OUT:-}" ]]; then
|
||||
JSON="$OUT"
|
||||
else
|
||||
JSON='{}'
|
||||
fi
|
||||
|
||||
# ---- decode ------------------------------------------------------------------
|
||||
username=$(php -r 'echo json_decode($argv[1],true)["username"]??"";' "$JSON")
|
||||
smtp_ok=$(php -r 'echo (json_decode($argv[1],true)["smtp"]["ok"]??false)?"1":"0";' "$JSON")
|
||||
smtp_err=$(php -r 'echo json_decode($argv[1],true)["smtp"]["error"]??"";' "$JSON")
|
||||
ptv_ok=$(php -r 'echo (json_decode($argv[1],true)["peertube"]["ok"]??false)?"1":"0";' "$JSON")
|
||||
ptv_err=$(php -r 'echo json_decode($argv[1],true)["peertube"]["error"]??"";' "$JSON")
|
||||
|
||||
# ---- render with gum ---------------------------------------------------------
|
||||
gum style "Username : $username" --foreground 214
|
||||
[[ "$SHOW_PWD" -eq 1 ]] && gum style "Password : $(php -r 'echo json_decode($argv[1],true)["password"]??"";' "$JSON")" --foreground 214
|
||||
|
||||
gum style "SMTP" --padding "0 1" --foreground 240 --bold
|
||||
if [[ "$smtp_ok" == "1" ]]; then
|
||||
gum style " ✓ SMTP AUTH succeeded (connect + auth + close, no mail sent)" --foreground 42
|
||||
else
|
||||
gum style " ✗ SMTP failed: ${smtp_err}" --foreground 196
|
||||
fi
|
||||
|
||||
gum style "PeerTube (direct OAuth password grant, no portal)" --padding "0 1" --foreground 240 --bold
|
||||
if [[ "$ptv_ok" == "1" ]]; then
|
||||
gum style " ✓ PeerTube issued an access token with these creds" --foreground 42
|
||||
else
|
||||
gum style " ✗ PeerTube failed: ${ptv_err}" --foreground 196
|
||||
fi
|
||||
|
||||
# ---- verdict + log -------------------------------------------------------------
|
||||
verdict="UNKNOWN"
|
||||
if [[ "$ptv_ok" == "1" ]]; then verdict="PEERTUBE_TOKENS_OK"; fi
|
||||
status_line="$verdict"
|
||||
if [[ "$ptv_ok" == "0" && "$smtp_ok" == "1" ]]; then
|
||||
status_line="SMTP_OK__PEERTUBE_BAD"
|
||||
gum style "" --foreground 214
|
||||
gum style " Root-cause hint:" --foreground 214 --bold
|
||||
gum style " Credentials are valid (SMTP auth works), but PeerTube's password" --foreground 214
|
||||
gum style " grant rejects them → the SSO/portal almost certainly broke PeerTube's" --foreground 214
|
||||
gum style " direct API password-grant path, even though the same login works" --foreground 214
|
||||
gum style " through portail.erg.be. See the curl repro in the PHP helper/todo." --foreground 214
|
||||
elif [[ "$ptv_ok" == "0" && "$smtp_ok" == "0" ]]; then
|
||||
status_line="BOTH_BAD"
|
||||
gum style " Both probes failed → the stored credentials themselves are wrong/stale." --foreground 214
|
||||
elif [[ "$ptv_ok" == "1" && "$smtp_ok" == "1" ]]; then
|
||||
status_line="BOTH_OK"
|
||||
gum style " Both SMTP and PeerTube accept these credentials." --foreground 42
|
||||
fi
|
||||
|
||||
# ---- append to log (NEVER the password) -----------------------------------------
|
||||
{
|
||||
echo "===== $(date '+%Y-%m-%d %H:%M:%S') | $status_line | user=$username | db=$DB_PATH"
|
||||
echo " SMTP : ok=$smtp_ok err=$(printf '%q' "$smtp_err")"
|
||||
echo " PeerTube : ok=$ptv_ok err=$(printf '%q' "$ptv_err")"
|
||||
} >> "$LOG"
|
||||
gum style "" --foreground 240
|
||||
gum style "Logged (no password stored) → $LOG" --foreground 240
|
||||
|
||||
# Exit 0 only when BOTH probes succeeded.
|
||||
[[ "$smtp_ok" == "1" && "$ptv_ok" == "1" ]] && exit 0 || exit 1
|
||||
Reference in New Issue
Block a user