n4bb12 / verdaccio-github-oauth-ui

📦🔐 GitHub OAuth plugin for Verdaccio
https://verdaccio.org
MIT License
71 stars 45 forks source link

NPM user undefined after token authentication success #164

Closed productiveme closed 1 year ago

productiveme commented 1 year ago

Bug Report

Versions

Version
Verdaccio 5.14.0
This plugin 5.0.2
Node 14.20.0

Environment

Name Version
Package manager npm 6.14.7
Browser brave [Version 1.42.97 Chromium: 104.0.5112.102 (Official Build) (arm64)]
Operating system macOS 12.5.1

Observed behavior

I'm unable to publish a scoped package to my verdaccio self-hosted (docker) server. When I attempt a npm publish I get

npm notice Publishing to https://npm.productive.me/
npm ERR! code E401
npm ERR! Unable to authenticate, your authentication token seems to be invalid.
...

And the server logs show (some parts redacted)

http --- 172.17.0.11 requested 'PUT /@productiveme%2fpackage'
(node:8) [DEP0106] DeprecationWarning: crypto.createDecipher is deprecated.
(Use `node --trace-deprecation ...` to show where the warning was created)
error--- undefined is forbidden publish for @productiveme/package
http --- 401, user: null(102.39.99.171, 172.68.186.175 via 172.17.0.11), req: 'PUT /@productiveme%2fpackage', error: authorization required to publish package @productiveme/package

Expected behavior

The package should be allowed to publish for authenticated users belonging to the github organization for this scope.

Steps to reproduce

npm publish --registry=https://npm.productive.me

Additional context

After running npx verdaccio-github-oauth-ui --registry https://npm.productive.me I'm successfully authenticated with a token in my ~/.npmrc file. But when I attempt a npm whoami --registry https://npm.productive.me I get undefined.

My config.yaml file contains these sections (among others)

auth:
  github-oauth-ui:
    client-id: GITHUB_CLIENT_ID
    client-secret: GITHUB_CLIENT_SECRET
    token: GITHUB_TOKEN

packages:    
  '@productiveme/*':
    access: $all
    publish: github/org/productive-me
    unpublish: github/org/productive-me

middlewares:
  audit:
    enabled: true
  github-oauth-ui:
    enabled: true

My package's package.json file contains the directive:

 "publishConfig": {
    "@productiveme:registry":"https://npm.productive.me/"
  },

GITHUB_TOKEN scopes: read:org, repo

n4bb12 commented 1 year ago

Hi Jaco, thanks for reporting.

Not sure if this might be causing issues but the plugin requires at least node 16 and your npm is also two major versions behind.

Your config looks good to me.

Before I dig deeper, could you make sure those binaries are up-to-date?

productiveme commented 1 year ago

Looking at the latest verdaccio docker image, it seems this is the latest node/npm versions as supported by the verdaccio app? https://hub.docker.com/layers/verdaccio/verdaccio/latest/images/sha256-fcf49e2ab2864a903234129fd8627b6a1829545c40d1a0964ec8b788d1beac69?context=explore

n4bb12 commented 1 year ago

Please see the plugin documentation. The version range supported by Verdaccio is not necessarily the one supported by the plugin 😵.

productiveme commented 1 year ago

Thanks, I see that. Do you have advice on how to set up verdaccio using the "Extending the Verdaccio Docker Image"?

My Dockerfile looks like this at the moment:

FROM node:lts-alpine as builder

RUN mkdir -p /verdaccio/plugins &&\
  cd /verdaccio/plugins &&\
  npm install --global-style --no-bin-links --omit=optional verdaccio-github-oauth-ui

FROM verdaccio/verdaccio:latest

ADD verdaccio.yaml /verdaccio/conf/config.yaml

COPY --chown=$VERDACCIO_USER_UID:root --from=builder \
  /verdaccio/plugins/node_modules/verdaccio-github-oauth-ui \
  /verdaccio/plugins/verdaccio-github-oauth-ui

The latest verdaccio/verdaccio image ends up with Node 14.

n4bb12 commented 1 year ago

Hmm, I can see now how it would be useful if the plugin supported the same versions as verdaccio.

I'm afraid I can't give you advice on updating Nodejs in docker.

Your Dockerfile doesn't seem to work though, I'm getting

error--- plugin not found. try npm install verdaccio-github-oauth-ui

If you can provide a working Dockerfile, I might spot the issue if something else is causing your problem.

Lukinoh commented 1 year ago

Hello,

I suppose I have the same problem. Maybe the difference is that I am trying to run it without an organization, but just on my GitHub account. I tried as you propose to run Verdaccio 5.13.3 with Node16, but it did not work.

Instruction on how I've created the image 1. `git clone git@github.com:verdaccio/verdaccio.git` 2. `cd verdaccio` 3. `git checkout v5.13.3` 4. Modify DockerFile with the following diff ``` diff --git a/Dockerfile b/Dockerfile index 354048d3..2d54704d 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM --platform=${BUILDPLATFORM:-linux/amd64} node:14.20.0-alpine as builder +FROM --platform=${BUILDPLATFORM:-linux/amd64} node:16.17.0-alpine as builder ENV NODE_ENV=production \ VERDACCIO_BUILD_REGISTRY=https://registry.npmjs.org \ @@ -24,7 +24,7 @@ RUN yarn config set npmRegistryServer $VERDACCIO_BUILD_REGISTRY && \ yarn cache clean && \ yarn workspaces focus --production -FROM node:14.20.0-alpine +FROM node:16.17.0-alpine LABEL maintainer="https://github.com/verdaccio/verdaccio" ENV VERDACCIO_APPDIR=/opt/verdaccio \ @@ -34,6 +34,7 @@ ENV VERDACCIO_APPDIR=/opt/verdaccio \ VERDACCIO_PROTOCOL=http ENV PATH=$VERDACCIO_APPDIR/docker-bin:$PATH \ HOME=$VERDACCIO_APPDIR +ENV DEBUG=verdaccio* WORKDIR $VERDACCIO_APPDIR @@ -41,10 +42,13 @@ RUN apk --no-cache add openssl dumb-init RUN mkdir -p /verdaccio/storage /verdaccio/plugins /verdaccio/conf + COPY --from=builder /opt/verdaccio-build . ADD conf/docker.yaml /verdaccio/conf/config.yaml +RUN yarn add verdaccio-github-oauth-ui@5 + RUN adduser -u $VERDACCIO_USER_UID -S -D -h $VERDACCIO_APPDIR -g "$VERDACCIO_USER_NAME user" -s /sbin/nologin $VERDACCIO_USER_NAME && \ chmod -R +x $VERDACCIO_APPDIR/bin $VERDACCIO_APPDIR/docker-bin && \ chown -R $VERDACCIO_USER_UID:root /verdaccio/storage && \ ``` 5. Build the new image: ``docker build . -f ./Dockerfile -t custom/verdaccio`

This is my Verdaccio configuration:

storage: /verdaccio/storage

plugins: /verdaccio/plugins

https:
  key: /verdaccio/conf/verdaccio-key.pem
  cert: /verdaccio/conf/verdaccio-cert.pem
  ca: /verdaccio/conf/verdaccio-csr.pem

middlewares:
  github-oauth-ui:
    enabled: true

auth:
  github-oauth-ui:
    client-id: GITHUB_CLIENT_ID
    client-secret: GITHUB_CLIENT_SECRET
    token: GITHUB_TOKEN

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

packages:
  '**':
    access: $all
    publish: $authenticated

logs:
  - {type: stdout, format: pretty, level: http}

The log looks like this:

verdaccio-demo  |  http --- 172.25.0.1 requested 'PUT /another-plugin'
verdaccio-demo  | 2022-09-26T10:27:51.092Z verdaccio:auth api middleware using legacy auth token
verdaccio-demo  | 2022-09-26T10:27:51.093Z verdaccio:auth authenticating 'Lukinoh'
verdaccio-demo  | 2022-09-26T10:27:51.366Z verdaccio:auth authenticating 'Lukinoh'
verdaccio-demo  | [github-oauth-ui] User successfuly authenticated: {
verdaccio-demo  |   name: 'Lukinoh',
verdaccio-demo  |   groups: [ '$all', '@all', '$authenticated', '@authenticated' ],
verdaccio-demo  |   real_groups: []
verdaccio-demo  | }
verdaccio-demo  |  error--- authenticating for user Lukinoh failed. Error: bad username/password, access denied
verdaccio-demo  | 2022-09-26T10:27:51.369Z verdaccio [middleware/allow]['publish'] allow for undefined
verdaccio-demo  | 2022-09-26T10:27:51.369Z verdaccio:auth allow publish for 'another-plugin' init | plugins: [CENSORED_AS_IT_DISPLAYS_TOKENS]
verdaccio-demo  | 2022-09-26T10:27:51.369Z verdaccio:auth allow publish for 'another-plugin' plugin does not implement allow_publish
verdaccio-demo  | 2022-09-26T10:27:51.369Z verdaccio [auth/allow_action]: user: undefined
verdaccio-demo  | 2022-09-26T10:27:51.369Z verdaccio [auth/allow_action]: hasPermission? false} for user: undefined
verdaccio-demo  |  error--- undefined is forbidden publish for another-plugin
verdaccio-demo  |  http --- 200, user: null(172.25.0.1), req: 'PUT /another-plugin', bytes: 18727/0

When I run npm whoami --registry https://localhost:4873, I get this:

verdaccio-demo  |  http --- 172.25.0.1 requested 'GET /-/whoami'
verdaccio-demo  | 2022-09-26T10:32:08.104Z verdaccio:auth api middleware using legacy auth token
verdaccio-demo  | 2022-09-26T10:32:08.104Z verdaccio:auth authenticating 'Lukinoh'
verdaccio-demo  |  http --- 200, user: null(172.25.0.1), req: 'GET /-/whoami', bytes: 0/0
verdaccio-demo  | [github-oauth-ui] User successfuly authenticated: {
verdaccio-demo  |   name: 'Lukinoh',
verdaccio-demo  |   groups: [ '$all', '@all', '$authenticated', '@authenticated' ],
verdaccio-demo  |   real_groups: []
verdaccio-demo  | }
verdaccio-demo  | 2022-09-26T10:32:08.387Z verdaccio:auth authenticating 'Lukinoh'
verdaccio-demo  |  error--- authenticating for user Lukinoh failed. Error: bad username/password, access denied
Lukinoh commented 1 year ago

I am not sure it is useful, but here some additional details:

Here you have:

It looks like it is using the "defaultPlugin" of "auth-utils.ts" of Verdaccio instead

verdaccio-demo  | authenticate(_user, _password, cb) {
verdaccio-demo  |       // pragma: allowlist secret
verdaccio-demo  |       cb(_utils.ErrorCode.getForbidden(_constants.API_ERROR.BAD_USERNAME_PASSWORD));
verdaccio-demo  |     }
verdaccio-demo  | ForbiddenError: bad username/password, access denied
verdaccio-demo  |     at getError (/opt/verdaccio/.yarn/cache/@verdaccio-commons-api-npm-10.2.0-d36a19383f-d93c93220a.zip/node_modules/@verdaccio/commons-api/lib/index.js:113:45)
verdaccio-demo  |     at Object.getForbidden (/opt/verdaccio/.yarn/cache/@verdaccio-commons-api-npm-10.2.0-d36a19383f-d93c93220a.zip/node_modules/@verdaccio/commons-api/lib/index.js:139:10)
verdaccio-demo  |     at Object.authenticate (/opt/verdaccio/build/lib/auth-utils.js:129:27)
verdaccio-demo  |     at next (/opt/verdaccio/build/lib/auth.js:117:14)
verdaccio-demo  |     at /opt/verdaccio/build/lib/auth.js:157:9
verdaccio-demo  |     at $259f9df0161ea3dd$export$901cf72dabf2112a.authenticate (/opt/verdaccio/.yarn/$$virtual/verdaccio-github-oauth-ui-virtual-72fee02e5c/0/cache/verdaccio-github-oauth-ui-npm-5.0.3-0395108440-a7be1ff1e7.zip/node_modules/verdaccio-github-oauth-ui/dist/server/index.js:712:13) {
verdaccio-demo  |   code: 403

I've double checked manually, the userName, and userToken passed to the authenticate method seems correct and working.

n4bb12 commented 1 year ago

I can reproduce the problem by using your config @Lukinoh. I'm suspecting that the problem you're both observing is related to the API security mode. Based on the configurations you both provided, you're using the legacy encryption. But I can no longer reproduce it when switching to JWT API security.

See for more context:

Lukinoh commented 1 year ago

Thank you very much at solved my problem.

And now I realize that in your example of verdaccio.yaml, in your repository, there was the security entry 🤦 . As I started from Verdaccio and then followed the steps of your documentation I missed that 😢.

I think it would be useful to add a small chapter in the configuration.md about adding the security entry, or in the troubleshooting.md.

ochicf commented 1 year ago

I think it would be useful to add a small chapter in the configuration.md about adding the security entry, or in the troubleshooting.md.

Just wanting to second this as I took as a starting point a yml file from another repo and I've been battling with this for a couple of hours.

Thank you so much for raising this and for solving it!

n4bb12 commented 1 year ago

Thank you for the feedback, I'll add something to the troubleshooting section.

n4bb12 commented 1 year ago

One thought regarding your config @Lukinoh

packages:
  '**':
    access: $all
    publish: $authenticated

Doesn't that mean that anybody with a GitHub account can sign in and publish packages? If there is no limitation based on org, repo, team, or user, isn't it somewhat fake authentication?

I'm thinking if it would be a good idea to throw an error in such a case.

This would also avoid authentication failure with legacy api security since the authenticated user groups would no longer be empty.

Lukinoh commented 1 year ago

As I was trying to find out from where the error came from, I simplified the configuration to have the bare minimum. I have a more complex configuration that takes into account users and orgs, and that does not allow anyone to publish.

I am not sure you should throw an error on a valid configuration even though it is bad. Maybe a warning. To be honest, I don't have enough insight to help you more.

n4bb12 commented 1 year ago

I added this to the configuration guide and troubleshooting section:

Thanks for bringing it up!