yarnpkg / berry

📦🐈 Active development trunk for Yarn ⚒
https://yarnpkg.com
BSD 2-Clause "Simplified" License
7.41k stars 1.11k forks source link

[Bug?]: yarn 4.0.2 ignores npmAlwaysAuth in ${PROJECT}/.yarnrc.yml #6097

Open gustafc opened 9 months ago

gustafc commented 9 months ago

Self-service

Describe the bug

(This is sort of a follow-up to #4341, where I tried to upgrade to yarn 3, which didn't work because it didn't use the token saved by yarn npm login.)

TL;DR: yarn install doesn't respect npmAlwaysAuth in the project-local .yarnrc.yml. It works if you log in using yarn npm login --always-auth.

Current situation

The problem

A bit of sleuthing (why can't I do yarn install --verbose?) has lead me to the following observations:

The only conclusion I can draw from this is that it doesn't use the token.

To reproduce

I couldn't figure out how to make Sherlock start a Nexus server for reproduction, so here's an old-fashioned shell script which

  1. creates a new project in /tmp with a local Nexus configured,
  2. starts a local Nexus using Docker,
  3. logs in to the local Nexus server,
  4. tries to yarn add a package, which triggers the error

If you change yarn npm login in the script to yarn npm login --always-auth, step 4 will work.

#!/bin/bash
set -exuo pipefail

UNIQUE_STRING=$(date '+%Y%m%d-%H%M%S')
PROJECT=/tmp/yarn4-auth-repro-$UNIQUE_STRING
# Step 1: Create a new project in /tmp
mkdir -p $PROJECT
cd $_
yarn init -2
echo '
unsafeHttpWhitelist:
  - localhost
npmRegistryServer: "http://localhost:8081/repository/npm-all"
npmAlwaysAuth: true
' >>.yarnrc.yml

# Step 2: Set up Nexus
NEXUS_CONTAINER=nexus-repro-container-$UNIQUE_STRING

docker run --rm --detach -p 8081:8081 --name $NEXUS_CONTAINER sonatype/nexus3@sha256:66fe12b1eb3e97bae72eb3c2c4e436499d41ff144cdfd1dcd0718df738304732
function cleanup {
  read -p "Stop Nexus docker container $NEXUS_CONTAINER? (y/n) " STOP_CONTAINER
  if [[ $STOP_CONTAINER == y* ]]; then
    docker stop $NEXUS_CONTAINER
  else
    echo "You can play around in the project by going to the following directory:"
    echo "  cd $PROJECT"
    echo "To stop the Nexus container, run:"
    echo "  docker stop $NEXUS_CONTAINER"
  fi
}
trap cleanup EXIT

while ! docker logs $NEXUS_CONTAINER | grep 'Started Sonatype Nexus OSS' ; do echo "Waiting for $NEXUS_CONTAINER to start..."; sleep 2; done
printf '\a'
NEXUS_USER=admin
NEXUS_PASS="$(docker exec $NEXUS_CONTAINER cat /nexus-data/admin.password)"
# # Change admin password
# curl --fail --verbose -u "$NEXUS_USER:$NEXUS_PASS" 'http://localhost:8081/service/rest/internal/ui/onboarding/change-admin-password' -X PUT --data-raw 'admin123'
# sleep 1
# NEXUS_PASS=admin123
# Disallow anonymous access
curl --fail --verbose -u "$NEXUS_USER:$NEXUS_PASS" 'http://localhost:8081/service/extdirect' -X POST -H 'Content-Type: application/json' --data-raw '{"action":"coreui_AnonymousSettings","method":"update","data":[{"enabled":false,"userId":"anonymous","realmName":"NexusAuthorizingRealm"}],"type":"rpc","tid":14}'

# Create npm repo proxy
curl --fail --verbose -u "$NEXUS_USER:$NEXUS_PASS" 'http://localhost:8081/service/extdirect' -X POST -H 'Content-Type: application/json' --data-raw '{"action":"coreui_Repository","method":"create","data":[{"attributes":{"npm":{"removeNonCataloged":false,"removeQuarantinedVersions":false},"proxy":{"remoteUrl":"https://registry.npmjs.org","contentMaxAge":1440,"metadataMaxAge":1440},"httpclient":{"blocked":false,"autoBlock":true,"connection":{"useTrustStore":false}},"storage":{"blobStoreName":"default","strictContentTypeValidation":true},"negativeCache":{"enabled":true,"timeToLive":1440},"cleanup":{"policyName":[]}},"name":"npm-proxy","format":"","type":"","url":"","online":true,"routingRuleId":"","authEnabled":false,"httpRequestSettings":false,"recipe":"npm-proxy"}],"type":"rpc","tid":31}'

# Create npm repo group (which is my real setup)
curl --fail --verbose -u "$NEXUS_USER:$NEXUS_PASS" 'http://localhost:8081/service/extdirect' -X POST -H 'Content-Type: application/json' --data-raw '{"action":"coreui_Repository","method":"create","data":[{"attributes":{"storage":{"blobStoreName":"default","strictContentTypeValidation":true},"group":{"memberNames":["npm-proxy"]}},"name":"npm-all","format":"","type":"","url":"","online":true,"recipe":"npm-group"}],"type":"rpc","tid":44}'

# Make NPM login work <https://issues.sonatype.org/browse/NEXUS-20170>
curl --fail --verbose -u "$NEXUS_USER:$NEXUS_PASS" 'http://localhost:8081/service/extdirect' -X POST -H 'Content-Type: application/json' --data-raw '{"action":"coreui_RealmSettings","method":"update","data":[{"realms":["NexusAuthenticatingRealm","NexusAuthorizingRealm","NpmToken"]}],"type":"rpc","tid":43}'

# Step 3: Login
(echo "$NEXUS_USER"; sleep 2; echo "$NEXUS_PASS") | yarn npm login
yarn npm whoami

# Step 4: Add any random package to make sure auth works (this will fail)
yarn add mkdirp@latest

Environment

System:
    OS: macOS 14.2.1
    CPU: (14) arm64 Apple M3 Max
  Binaries:
    Node: 20.9.0 - /private/var/folders/3x/6k490qcx7hg9tvzfxy1k8tyc0000gn/T/xfs-d788f556/node
    Yarn: 4.0.2 - /private/var/folders/3x/6k490qcx7hg9tvzfxy1k8tyc0000gn/T/xfs-d788f556/yarn
    npm: 10.1.0 - ~/.nvm/versions/node/v20.9.0/bin/npm

Additional context

No response

gustafc commented 8 months ago

No response for over a week. Is there anything more I can do to help? I'm willing to provide a fix it if someone points me in the right direction, I'm not familiar with the yarn codebase.

koshic commented 8 months ago

@gustafc try yarn npm login --always-auth. As far as I remember, yarn has a problems with merging authorization settings comes from ~/.yarnrc.yml & project .yarnrc.yml: auth settings treated like a single block (per repo), so empty 'alwaysAuth' in global config + 'alwaysAuth=true' in local config will produce empty 'alwaysAuth' in effective config for the particular repo (see yarn config output).

gustafc commented 8 months ago

@koshic Thanks, adding --always-auth works 🌟 So I'll rename the bug so reflect that the problem is that npmAlwaysAuth in project config is ignored.