fix: allow specifying an auth token for third-party registries
Summary
Currently if we are using a third-party registry, we are unable to initialize a react-native project under either of the following conditions:
- The registry requires authentication
- The registry includes a path (e.g.,
https://registry.example.com/fooinstead ofhttps://registry.example.com)
Related: https://github.com/react-native-community/cli/issues/2718
Test Plan
I am on an enterprise network with a third-party registry that requires authentication. After making the changes in this PR locally, I was able to initialize a react-native repository locally with the following commands:
yarn installnpm run buildchmod 755 packages/cli/build/bin.js- From another directory:
../../packages/cli/build/bin.js init --auth-token ... MyAwesomeProject
Checklist
- [X] Documentation is up to date.
- [X] Follows commit message convention described in CONTRIBUTING.md.
- [ ] For functional changes, my test plan has linked these CLI changes into a local
react-nativecheckout (instructions).
Do NPM not publish a library that the CLI could be using for registry communication? E.g. one that'd automatically obey .npmrc, etc. settings rather than the CLI doing a raw fetch()?
Do NPM not publish a library that the CLI could be using for registry communication? E.g. one that'd automatically obey .npmrc, etc. settings rather than the CLI doing a raw
fetch()?
That's a good callout: I think I was looking at a very old version of the tool that I had installed locally, and it was using some attributes that were only available via the registry and not npm info. I'll see if I can update my MR to use npm info --json instead.
Or maybe I was looking at a different code branch that we only hit if a specific --version is supplied. I'll dig into it a bit and update my MR
I updated my PR. Turns out there are two places where we currently fetch npm registry data (my initial change only updated one). The second one deals with the getTemplateVersion function, which AFAIK is only used when a specific --version argument is passed:
https://github.com/react-native-community/cli/blob/main/packages/cli/src/tools/npm.ts#L134
This second registry query does need to pull directly from the registry without an npm command, since it assumes it can view scripts information for all published version. This information is available by hitting the registry directly, but not available via npm commands.
So we could update the first registry query (which only cares about tags and versions) to use npm info, but since the second one requires hitting the registry it might make sense to keep them both the same
Wouldn't it be enough to provide the auth token in your root .npmrc file? Like this:
registry=https://registry.example.com/foo/
//registry.example.com/foo/:_authToken=npm_token
Wouldn't it be enough to provide the auth token in your root
.npmrcfile? Like this:
We do have that set up locally, which is enough for running npm install commands locally. There are two reasons why we cannot use this _authToken:
- The token in that file is not used as part of a
fetchcall - The auth token is one of the few npm configuration values that cannot be extracted with
npm configdue to security concerns
So there is no good way to extract that value and automatically add it to the headers
It looks like NPM publish this package which might be worth investigating as a replacement for the raw fetch? https://github.com/npm/npm-registry-fetch
...It's able to consume npm-style configuration values and has all the necessary logic for picking registries, handling scopes, and dealing with authentication details built-in...
It looks like NPM publish this package which might be worth investigating as a replacement for the raw fetch? https://github.com/npm/npm-registry-fetch
I experimented with this package a bit. It takes configuration values that are similar to what you would find in a .npmrc file, but it doesn't automatically read/parse the existing .npmrc files. So we could use this library instead of fetch, but we would still need to pass the authToken as an option
It takes configuration values that are similar to what you would find in a .npmrc file, but it doesn't automatically read/parse the existing .npmrc files. So we could use this library instead of fetch, but we would still need to pass the authToken as an option
So close to being helpful...
Does https://www.npmjs.com/package/@npmcli/config let you load the config via normal lookup methods & then pass it to npm-registry-fetch?