I've got a script that verifies a user has logged into a private npm registry (via "npm login") by greping for:
//registry-sub-url:_authToken=
... in:
~/.npmrc
However, this breaks down over time as the user's credentials expire (due to standard password expiration rules).
What's more, the helper scripts I've created have cannot differentiate between successful/failed npm login
calls, since the script always exits with 0
status.
Q: (1) How do we verify that npm login
succeeded? (2) How do identify when the npm token has expired?
I'm posting the workaround I came up with, but I'd love a better solution.
I've got Jenkins running this bash script periodically to test/verify my npm login
against a private registry:
#/bin/bash
# Suppress commands (Jenkins turns this on)
set +x
# Suppress color codes from NPM output (for proper grepping)
export TERM=dumb
# Stop on any error
set -e
NPM_USERNAME=...
NPM_PASSWORD=...
NPM_URL=...
NPM_EMAIL=...
WORKSPACE=... (in my case, set by Jenkins)
echo "========"
echo "Looking for previous failed login (cached credentials)..."
echo ""
# NOTE: A previous failed login can result in an ".npmrc" containing
# a username/password in lieu of an auth token. We look for this and
# remove it (logout) if it exists so that the cached credentials are
# not applied when we run "expect" to login
# (which would see different prompts from cached credentials).
# Chop off "http:"/"https:" prefix from URL
NPM_REPO_PREFIX=`sed -e 's~https\{0,1\}:\(.*\)~\1~' <<< "$NPM_URL"`
# NOTE: piping to /dev/null so the password isn't printed
set +e
grep -F "${NPM_REPO_PREFIX}:_password=" ~/.npmrc > /dev/null
GREP_EXIT="$?"
set -e
if [[ "$GREP_EXIT" == "0" ]]; then
echo "========"
echo "Logging out of repo..."
echo ""
npm logout --registry "$NPM_URL"
fi
echo "========"
echo "Logging into repo..."
echo ""
(/usr/bin/expect <<EOF
set timeout 10
spawn npm login --verbose --registry "$NPM_URL"
match_max 100000
expect "Username"
send "$NPM_USERNAME\r"
expect "Password"
send "$NPM_PASSWORD\r"
expect "Email"
send "$NPM_EMAIL\r"
expect {
timeout exit 1
expect eof
}
EOF
) | tee "$WORKSPACE/npm-login.out"
echo "========"
echo "Verifying output of login..."
echo ""
# NOTE: If the login fails, the npm command still exits with status "0",
# so we read the verbose output to see that the http server confirms
# successful with "http 201".
set +e
grep "npm http 201" "$WORKSPACE/npm-login.out"
GREP_EXIT="$?"
set -e
if [[ "$GREP_EXIT" != "0" ]]; then
>&2 echo "========"
>&2 echo "ERROR: Failed to login to repo [$NPM_REPO]"
exit 1
else
echo "========"
echo "SUCCESS: Logged into [$NPM_REPO]"
fi