19

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?

Ryan
  • 1,171
  • 1
  • 10
  • 23

4 Answers4

19

You might use npm whoami command.

$> npm whoami
${username}
$>  npm logout
 npm whoami
npm ERR! code ENEEDAUTH
npm ERR! need auth This command requires you to be logged in.
npm ERR! need auth You need to authorize this machine using `npm adduser`

npm ERR! A complete log of this run can be found in:
npm ERR!     /xxxxx/.npm/_logs/2019-02-06T10_21_10_780Z-debug.logged
Juan Picado
  • 1,823
  • 18
  • 33
  • 5
    So, unfortunately, this does nothing to check if the login is valid, just that it's persisted. I also vaguely remember that it doesn't gracefully handle the case where the original login failed, so a username/password was persisted instead of a token. I'd have to go back and experiment to be sure. Other readers of this article may find this command relevant, which I failed to mention. – Ryan Feb 16 '19 at 21:57
11

In the context of GitHub Packages: if you logged in using npm login --registry=https://npm.pkg.github.com, you can use npm whoami --registry=https://npm.pkg.github.com (same registry) to verify the currently logged in user.

$ npm login --registry=https://npm.pkg.github.com
Username: <your-user>
Password: <your-password-or-your-personal-access-token>
Email: (this IS public) <your@email.com>
Logged in as <your-user> on https://npm.pkg.github.com/.

$ npm whoami --registry=https://npm.pkg.github.com
<your-user>

If I only run npm whoami I get the error mentioned in the question.

Voronin
  • 159
  • 1
  • 7
  • 1
    This doesn't answer the OP's question. It only tells you that there is a token stored and not if it's expired. – GazB Nov 21 '22 at 07:56
1

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
Ryan
  • 1,171
  • 1
  • 10
  • 23
0

this problem is probably due to the fact that there is an .npmrc file in the npm whoami invocation file. if the token in that file is corrupt, this error appears. you can correct or delete the token value in the file and use the global token value.

Ahmet Şimşek
  • 1,391
  • 1
  • 14
  • 24