Berry: yarn npm login is not compatible with verdaccio

Created on 7 Mar 2020  Â·  13Comments  Â·  Source: yarnpkg/berry

Describe the bug

I have a private npm registry implemented by verdaccio which requires login for any access. When a certain user does not yet exist in the registry yarn npm login succeeds. However, as soon as this user tries to relogin with the same command there's a http error 409 (conflict).

I had reported this against verdaccio (https://github.com/verdaccio/verdaccio/issues/1737), since yarn2 login works fine for registry.yarnpkg.com. However, this was before I realized that new users may be created without problems.

To Reproduce

I'm sorry that I don't see like I could provide the repro with Sherlock :-(

1 You would have to install verdaccio, globally or locally, with yarn or npm and run it like this
[yarn run] verdaccio -c conf.yml with this conf.yml:

storage: ./storage

auth:
  htpasswd:
    file: ./htpasswd

security:
  api:
    jwt:
      sign:
        expiresIn: 30d
        notBefore: 0
  web:
    sign:
      expiresIn: 7d

uplinks:
  npmjs:
    url: https://registry.npmjs.org/

packages:
  '@*/*':
    access: $authenticated
    publish: $authenticated
    proxy: npmjs

  '**':
    access: $authenticated
    publish: $authenticated
    proxy: npmjs

logs:
  - {type: file, path: verdaccio.log, level: trace}

2 Furthermore I save this as .yarnrc.yml (you'd have to correct yarnPath, obviously)

yarnPath: "...\\.yarn\\releases\\yarn-berry.js"

unsafeHttpWhitelist:
  - "localhost"

npmRegistryServer: "http://localhost:4873"

3 Execute yarn npm login two times - the first will succeed, the second fail with a message like this:

➤ YN0001: HTTPError: Response code 409 (Conflict)
at EventEmitter. (...\releases\yarn-berry.js:24:327728)
at processTicksAndRejections (internal/process/task_queues.js:97:5)
➤ YN0000: Failed with errors in 4.09s

Environment if relevant (please complete the following information):

  • OS: [e.g. OSX, Linux, Windows, ...] windows 10
  • Node version [e.g. 8.15.0, 10.15.1, ...] 12.16.1
  • Yarn version [e.g. 2.0.0-rc1, ...] 2.0.0rc29
const cp = require('child_process')
const fs = require('fs')


const verdaccioConf=`
storage: ./storage

auth:
  htpasswd:
    file: ./htpasswd

uplinks:
  npmjs:
    url: https://registry.npmjs.org/

packages:
  '@*/*':
    access: $authenticated
    publish: $authenticated
    proxy: npmjs

  '**':
    access: $authenticated
    publish: $authenticated
    proxy: npmjs

logs:
  - {type: stdout, format: pretty, level: http}
`
fs.writeFileSync('config.yaml', verdaccioConf)


const htpasswd = `
test:$6FrCaT/v0dwE:autocreated 2020-06-09T16:43:43.706Z
`
fs.writeFileSync('htpasswd', htpasswd)


const  yarnrc = `
unsafeHttpWhitelist:
  - "localhost"

npmRegistryServer: "http://localhost:4873"
`
fs.writeFileSync('.yarnrc.yml', yarnrc)


await packageJsonAndInstall({
  dependencies: {
    'verdaccio': '4.5.1'
  }
})

cp.spawn('./node_modules/.bin/verdaccio')

await new Promise(resolve => setTimeout(resolve, 5000)) // a bit of a delay

const output = await yarn('yarn', 'npm', 'login') // test, test
expect(output).not.toContain('Response code 409 (Conflict)')

bug good first issue upholded

All 13 comments

I was able to reproduce this easily with Yarn 2.0.0-rc.31.
I ran verdaccio via the default Docker image:

$ docker run -it --rm --name verdaccio -p 4873:4873 verdaccio/verdaccio

Then first create a user via:

$ npm adduser --registry http://localhost:4873

Then configure the local registry in your .yarnrc.yml file:

npmScopes:
  testscope:
    npmPublishRegistry: "http://localhost:4873"
    npmRegistryServer: "http://localhost:4873"
    npmAlwaysAuth: true
unsafeHttpWhitelist:
  - "localhost"

followed by:

$ yarn npm login -s testscope

If you use the same credentials from adduser, the yarn login will fail and you will see the following error message from the Verdaccio process:

http <-- 409, user: null(172.17.0.1), req: 'PUT /-/user/org.couchdb.user:ringods', error: username is already registered

Hi! 👋

This issue looks stale, and doesn't feature the reproducible label - which implies that you didn't provide a working reproduction using Sherlock. As a result, it'll be closed in a few days unless a maintainer explicitly vouches for it or you edit your first post to include a formal reproduction (you can use the playground for that).

Note that we require Sherlock reproductions for long-lived issues (rather than standalone git repositories or similar) because we're a small team. Sherlock gives us the ability to check which bugs are still affecting the master branch at any given point, and decreases the amount of code we need to run on our own machines (thus leading to faster bug resolution faster). It helps us help you! 😃

If you absolutely cannot reproduce a bug on Sherlock (for example because it's a Windows-only issue), a maintainer will have to manually add the upholded label.

Tried a repro - still I don't know how to simulate input to "yarn npm login". Maybe someone could enlighten me...

I'm not sure if this will help to fix the bug, though.

The reproduction case in your issue seems broken (ie it neither pass nor fail due to throwing an unmanaged exception):

Error: Command failed: /usr/bin/node /github/workspace/scripts/actions/../run-yarn.js install

➤ YN0000: ┌ Resolution step
::group::Resolution step
➤ YN0001: │ RequestError: connect ECONNREFUSED 127.0.0.1:4873
    at ClientRequest.<anonymous> (/github/workspace/.yarn/cache/got-npm-11.1.3-91d4bdb9d6-dbfe82b33f.zip/node_modules/got/dist/source/core/index.js:792:25)
    at Object.onceWrapper (events.js:422:26)
    at ClientRequest.emit (events.js:327:22)
    at ClientRequest.origin.emit (/github/workspace/.yarn/cache/@szmarczak-http-timer-npm-4.0.5-03463d10ab-13d8f71dbd.zip/node_modules/@szmarczak/http-timer/dist/source/index.js:39:20)
    at Socket.socketErrorListener (_http_client.js:426:9)
    at Socket.emit (events.js:315:20)
    at emitErrorNT (internal/streams/destroy.js:92:8)
    at emitErrorAndCloseNT (internal/streams/destroy.js:60:3)
    at processTicksAndRejections (internal/process/task_queues.js:84:21)
    at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1141:16)
::endgroup::
➤ YN0000: └ Completed in 7.26s
➤ YN0000: Failed with errors in 7.26s

    at ChildProcess.exithandler (child_process.js:303:12)
    at ChildProcess.emit (events.js:315:20)
    at maybeClose (internal/child_process.js:1021:16)
    at Process.ChildProcess._handle.onexit (internal/child_process.js:286:5)

Remember: any non-Jest exceptions will cause the test to be reported as broken. If you expect something to pass without throwing, you must wrap it into something like await expect(...).resolves.toBeTruthy(). If you instead expect something to throw, you need to wrap it into await expect(...).rejects.toThrow().

The reproduction case in your issue seems broken (ie it neither pass nor fail due to throwing an unmanaged exception):

Error: Command failed: /usr/bin/node /github/workspace/scripts/actions/../run-yarn.js install

➤ YN0000: ┌ Resolution step
::group::Resolution step
➤ YN0001: │ RequestError: connect ECONNREFUSED 127.0.0.1:4873
    at ClientRequest.<anonymous> (/github/workspace/.yarn/cache/got-npm-11.1.3-91d4bdb9d6-dbfe82b33f.zip/node_modules/got/dist/source/core/index.js:792:25)
    at Object.onceWrapper (events.js:422:26)
    at ClientRequest.emit (events.js:327:22)
    at ClientRequest.origin.emit (/github/workspace/.yarn/cache/@szmarczak-http-timer-npm-4.0.5-03463d10ab-13d8f71dbd.zip/node_modules/@szmarczak/http-timer/dist/source/index.js:39:20)
    at Socket.socketErrorListener (_http_client.js:426:9)
    at Socket.emit (events.js:315:20)
    at emitErrorNT (internal/streams/destroy.js:92:8)
    at emitErrorAndCloseNT (internal/streams/destroy.js:60:3)
    at processTicksAndRejections (internal/process/task_queues.js:84:21)
    at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1141:16)
::endgroup::
➤ YN0000: └ Completed in 7.25s
➤ YN0000: Failed with errors in 7.25s

    at ChildProcess.exithandler (child_process.js:303:12)
    at ChildProcess.emit (events.js:315:20)
    at maybeClose (internal/child_process.js:1021:16)
    at Process.ChildProcess._handle.onexit (internal/child_process.js:286:5)

Remember: any non-Jest exceptions will cause the test to be reported as broken. If you expect something to pass without throwing, you must wrap it into something like await expect(...).resolves.toBeTruthy(). If you instead expect something to throw, you need to wrap it into await expect(...).rejects.toThrow().

Also it does not seem to allow to start verdaccio...

BTW, if I copy the auth-token received by "npm login" into .yarnrc.yml the registry can be accessed without probs.

BTW, if I copy the auth-token received by "npm login" into .yarnrc.yml the registry can be accessed without probs.

Hi! It didn't help me. I add new user into Verdaccio, then copy authToken into .yarnrn.yml and I keep getting http error with code 409.

The verdaccio logs shows that npm has some extra logic when a 409 is returned:

# yarn npm login -s testscope
 http <-- 409, user: null(172.17.0.1), req: 'PUT /-/user/org.couchdb.user:bram', error: username is already registered

# npm login --registry http://localhost:4873
 http <-- 404, user: null(172.17.0.1), req: 'POST /-/v1/login', bytes: 24/150
 http <-- 409, user: null(172.17.0.1), req: 'PUT /-/user/org.couchdb.user:bram', error: username is already registered
 http <-- 200, user: null(172.17.0.1), req: 'GET /-/user/org.couchdb.user:bram?write=true', bytes: 0/51
 http <-- 201, user: bram(172.17.0.1), req: 'PUT /-/user/org.couchdb.user:bram/-rev/undefined', bytes: 166/85

The logic in question can be found here: https://github.com/npm/npm-profile/blob/6b643238ff7e1e6ec5544b0771142a8d0c537925/index.js#L162

The reproduction case in your issue seems broken (ie it neither pass nor fail due to throwing an unmanaged exception):

Error: Command failed: /usr/bin/node /github/workspace/scripts/actions/../run-yarn.js install

➤ YN0000: ┌ Resolution step
::group::Resolution step
➤ YN0001: │ RequestError: connect ECONNREFUSED 127.0.0.1:4873
    at ClientRequest.<anonymous> (/github/workspace/.yarn/cache/got-npm-11.1.3-91d4bdb9d6-dbfe82b33f.zip/node_modules/got/dist/source/core/index.js:792:25)
    at Object.onceWrapper (events.js:422:26)
    at ClientRequest.emit (events.js:327:22)
    at ClientRequest.origin.emit (/github/workspace/.yarn/cache/@szmarczak-http-timer-npm-4.0.5-03463d10ab-13d8f71dbd.zip/node_modules/@szmarczak/http-timer/dist/source/index.js:39:20)
    at Socket.socketErrorListener (_http_client.js:426:9)
    at Socket.emit (events.js:315:20)
    at emitErrorNT (internal/streams/destroy.js:92:8)
    at emitErrorAndCloseNT (internal/streams/destroy.js:60:3)
    at processTicksAndRejections (internal/process/task_queues.js:84:21)
    at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1141:16)
::endgroup::
➤ YN0000: └ Completed in 7.37s
➤ YN0000: Failed with errors in 7.38s

    at ChildProcess.exithandler (child_process.js:303:12)
    at ChildProcess.emit (events.js:315:20)
    at maybeClose (internal/child_process.js:1021:16)
    at Process.ChildProcess._handle.onexit (internal/child_process.js:286:5)

Remember: any non-Jest exceptions will cause the test to be reported as broken. If you expect something to pass without throwing, you must wrap it into something like await expect(...).resolves.toBeTruthy(). If you instead expect something to throw, you need to wrap it into await expect(...).rejects.toThrow().

I've removed the repro tag from the OP. Even though it's probably possible to get it running in sherlock, it would be hard to do and it's easy enough to reproduce manually.

I'll give it a try 🤞

any news here?

npmAlwaysAuth: true
npmAuthToken: xxxxMyToken

npmRegistryServer: "http://localhost:4873"

npmScopes:
  myscope:
    npmAlwaysAuth: true
    npmAuthToken: xxxxMyToken
    npmPublishRegistry: "http://localhost:4873"
    npmRegistryServer: "http://localhost:4873"

unsafeHttpWhitelist:
  - localhost
yarn npm login
➤ YN0000: Logging in to http://localhost:4873

✔ Username: · dmoosocool
✔ Password: · *************

➤ YN0001: HTTPError: Response code 409 (Conflict)
    at se.<anonymous> (/.yarn/releases/yarn-sources.cjs:23:10082)
    at processTicksAndRejections (internal/process/task_queues.js:97:5)
➤ YN0000: Failed with errors in 11s 413ms
yarn npm whoami
➤ YN0000: undefined
➤ YN0000: Done in 0s 49ms
yarn npm publish
➤ YN0041: Invalid authentication (as an unknown user)
➤ YN0000: Failed with errors in 0s 150ms
Was this page helpful?
0 / 5 - 0 ratings

Related issues

janicduplessis picture janicduplessis  Â·  4Comments

joshmeads picture joshmeads  Â·  4Comments

Santas picture Santas  Â·  3Comments

Bessonov picture Bessonov  Â·  4Comments

kiprasmel picture kiprasmel  Â·  3Comments