Anmeldung fehlgeschlagen: sagen, woran es liegt

Die Meldung nannte bisher nur die aufgerufene Adresse. Antwort,
HTTP-Code und curls eigene Fehlermeldung wurden weggeworfen - also
genau das, woran man es erkennt. Uebrig blieb Raten.

Jetzt werden alle drei eingesammelt und ausgewertet:

  HTTP 400/401  Der Proxy Manager hat geantwortet und abgelehnt. Damit
                ist auch gesagt, dass Port, Netz und Proxy stimmen. Die
                Meldung der Schnittstelle steht dabei ("Invalid email or
                password"), dazu der Hinweis auf npm-reset, falls das
                Konto nie angelegt wurde.
  HTTP 000      Gar keine Antwort. Der Reihe nach wird geprueft und
                benannt: NPM_ENABLED=off, Container laeuft nicht, auf
                dem Port lauscht nichts, oder er antwortet nur nicht.
  HTTP 5xx      Es hat etwas geantwortet, aber nicht wie erwartet.

Dazu: ist die Antwort HTML statt JSON, wird das ausdruecklich gesagt und
die erste Zeile gezeigt. Damit ist auf einen Blick erkennbar, dass ein
HTTP-Proxy geantwortet hat und nicht der Proxy Manager - im Test
"<html><head><title>502 Proxy Error</title>...".

Beim Pruefen der Faelle ist ein Fehler aufgefallen: container_running
benutzt RUNTIME ohne Absicherung. War die Runtime nicht erkannt, brach
die Fehlerdiagnose unter "set -u" mit "RUNTIME ist nicht gesetzt" ab -
ausgerechnet die Ausgabe, die helfen soll. Ohne erkannte Runtime lautet
die Antwort jetzt schlicht "nein".

Nebenbei korrigiert: NPM antwortet bei falschen Zugangsdaten mit 400,
nicht mit 401 - der erste Entwurf fing den haeufigsten Fall nicht.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-09-20 23:56:49 +02:00
co-authored by Claude Opus 5
parent eb29db0130
commit 62ccafbbd1
4 changed files with 204 additions and 22 deletions
+124 -20
View File
@@ -3769,31 +3769,135 @@ EOF
fi
return 1
fi
local body
body="$(curl -sS --max-time 20 --noproxy '*' -X POST "$base/api/tokens" \
# Antwort, HTTP-Code und curls eigene Fehlermeldung getrennt
# einsammeln - ohne die drei laesst sich hinterher nicht sagen, WORAN
# es lag, und genau das ist hier der haeufigste Zeitfresser.
local body code cerr rc=0
cerr="$(mktemp)"
body="$(curl -sS --max-time 20 --noproxy '*' -w '\n%{http_code}' \
-X POST "$base/api/tokens" \
-H 'Content-Type: application/json' \
-d "{\"identity\":\"$NPM_ADMIN_EMAIL\",\"secret\":\"$NPM_ADMIN_PASSWORD\"}" 2>/dev/null)" || true
-d "{\"identity\":\"$NPM_ADMIN_EMAIL\",\"secret\":\"$NPM_ADMIN_PASSWORD\"}" \
2>"$cerr")" || rc=$?
code="${body##*$'\n'}"; body="${body%$'\n'*}"
case "$code" in ''|*[!0-9]*) code=000 ;; esac
local tok; tok="$(json_str "$body" token)"
if [ -z "$tok" ]; then
err "Anmeldung am Proxy Manager fehlgeschlagen."
local m; m="$(json_str "$body" message)"
if [ -n "$m" ]; then printf ' Antwort: %s\n' "$m" >&2; fi
printf ' Geprueft wurde: %s\n' "$base/api/tokens" >&2
# In Kundennetzen mit Zwangsproxy ist das die haeufigste Ursache
# fuer eine Fehlermeldung, die nach einem API-Problem aussieht.
if [ -n "${http_proxy:-}${HTTP_PROXY:-}${https_proxy:-}${HTTPS_PROXY:-}" ]; then
printf '
In dieser Umgebung steht ein HTTP-Proxy. Nimmt no_proxy die lokalen
Adressen nicht aus, geht selbst diese Anfrage an ihn - dann meldet
er den Fehler, nicht der Proxy Manager. Nachsehen mit:
%s noproxy
' "$SELF" >&2
fi
return 1
if [ -n "$tok" ]; then
rm -f "$cerr"
printf '%s' "$tok"
return 0
fi
printf '%s' "$tok"
err "Anmeldung am Proxy Manager fehlgeschlagen."
printf ' Aufgerufen : %s\n' "$base/api/tokens" >&2
printf ' Konto : %s\n' "${NPM_ADMIN_EMAIL:-<leer>}" >&2
printf ' HTTP-Code : %s\n' "$code" >&2
local cmsg; cmsg="$(sed -n '1p' "$cerr" 2>/dev/null)"
if [ -n "$cmsg" ]; then printf ' curl sagt : %s\n' "$cmsg" >&2; fi
rm -f "$cerr"
# Der Proxy Manager verpackt seine Meldung in "error" - sie ist die
# nuetzlichste Zeile ueberhaupt und gehoert nach oben, nicht ans Ende.
local m; m="$(json_str "$body" message)"
if [ -n "$m" ]; then printf ' Antwort : %s\n' "$m" >&2; fi
printf '\n %sWoran es liegen kann%s\n' "$C_BLD" "$C_RST" >&2
case "$code" in
400|401|403)
# Es hat geantwortet - der Weg stimmt also, nur die Daten nicht.
printf ' Der Proxy Manager hat geantwortet und die Anmeldung abgelehnt.
Der Weg dorthin stimmt also - Port, Netz und Proxy sind in Ordnung.\n' >&2
case "$m" in
*"fewer than"*|*"must NOT"*|*"required"*)
printf '
Die Anfrage war unvollstaendig - meist ein leerer Wert in der .env:
NPM_ADMIN_EMAIL = %s
NPM_ADMIN_PASSWORD = %s
Setzen mit: %s config set NPM_ADMIN_PASSWORD <kennwort>\n' \
"${NPM_ADMIN_EMAIL:-<leer>}" \
"$([ -n "${NPM_ADMIN_PASSWORD:-}" ] && echo '<gesetzt>' || echo '<leer>')" \
"$SELF" >&2 ;;
*)
printf '
Konto oder Kennwort stimmt nicht. Beide stehen in der .env:
%s config set NPM_ADMIN_EMAIL <adresse>
%s config set NPM_ADMIN_PASSWORD <kennwort>
Gibt es das Konto ueberhaupt? Seit Version 2.15 legt der Proxy
Manager keine Standardzugangsdaten an; das Konto entsteht nur beim
ERSTEN Start mit leerer Datenbank aus NPM_ADMIN_EMAIL/-PASSWORD.
War die Datenbank damals schon da, wurde es nie angelegt:
%s npm-reset (Datenbank beiseite, Konto entsteht neu)
Oder von Hand in der Oberflaeche: %s browser\n' \
"$SELF" "$SELF" "$SELF" "$SELF" >&2 ;;
esac
;;
000)
printf ' Es kam ueberhaupt keine HTTP-Antwort.\n' >&2
# Der Reihe nach das Naheliegende pruefen und BENENNEN
if ! npm_enabled; then
printf ' -> NPM_ENABLED=off - der Proxy Manager soll gar nicht laufen.
Einschalten: %s npm-enable on\n' "$SELF" >&2
elif ! container_running "$NPM_CONTAINER_NAME"; then
printf ' -> Der Container "%s" laeuft nicht.
Starten: %s up\n' "$NPM_CONTAINER_NAME" "$SELF" >&2
elif ! port_in_use "${NPM_ADMIN_PORT:-81}"; then
printf ' -> Auf Port %s lauscht nichts.
Der Container laeuft, aber die Oberflaeche ist dort nicht zu
erreichen. Nachsehen: %s logs
Port pruefen/aendern: %s npm-port\n' \
"${NPM_ADMIN_PORT:-81}" "$SELF" "$SELF" >&2
else
printf ' -> Port %s ist belegt, antwortet aber nicht auf diese Anfrage.
Vielleicht startet der Dienst noch: %s proxy restart\n' \
"${NPM_ADMIN_PORT:-81}" "$SELF" >&2
fi
case "$cmsg" in
*proxy*|*Proxy*)
printf ' -> curl nennt einen Proxy. Pruefen: %s noproxy\n' "$SELF" >&2 ;;
esac
;;
5??)
printf ' Es hat etwas geantwortet, aber mit einem Serverfehler.
Kommt die Antwort ueberhaupt vom Proxy Manager? Ein
HTTP-Proxy im Netz antwortet an dieser Stelle gern selbst:
%s noproxy\n' "$SELF" >&2
;;
*)
printf ' Unerwartete Antwort - erwartet wurde ein Feld "token".\n' >&2
;;
esac
# Sieht die Antwort nach einer Webseite aus, kommt sie nicht von der
# Schnittstelle - das ist das sicherste Zeichen fuer einen Proxy
# oder einen fremden Dienst auf dem Port.
case "$body" in
'<'*|*'<html'*|*'<HTML'*)
printf '\n %sDie Antwort ist HTML, kein JSON%s - sie stammt also nicht von der
Schnittstelle des Proxy Managers, sondern von etwas davor
(HTTP-Proxy, anderer Dienst auf dem Port). Erste Zeile:
%s\n' "$C_YEL" "$C_RST" "$(printf '%s' "$body" | sed -n '1p' | cut -c1-70)" >&2 ;;
'')
: ;;
*)
if [ -z "$m" ]; then
printf '\n Antwort (gekuerzt): %s\n' "$(printf '%s' "$body" | tr -d '\n' | cut -c1-120)" >&2
fi ;;
esac
if [ -n "${http_proxy:-}${https_proxy:-}${HTTPS_PROXY:-}" ]; then
printf '
In dieser Umgebung steht ein HTTP-Proxy. Die eigenen Aufrufe gehen
zwar mit "--noproxy" daran vorbei, eigene Tests aber nicht:
%s noproxy\n' "$SELF" >&2
fi
printf '\n' >&2
return 1
}
# npm_api METHODE PFAD [JSON] -> Antwort auf stdout, HTTP-Code via npm_code
NPM_CODE_FILE="${TMPDIR:-/tmp}/.cmk-manage-npmcode.$$"
trap 'rm -f "$NPM_CODE_FILE"' EXIT