Skip to content

Commit

Permalink
feat: accept registry-scoped certfile and keyfile as credentials
Browse files Browse the repository at this point in the history
Closes npm#4765
RFC: npm/rfcs#591

While this doesn't directly allow top-level cert/key as credentials (per the
original issue), it's a more targeted/secure approach that accomplishes the
same end-result; the new options are scoped to a specific registry, and the
actual cert/key contents are much less likely to be exposed. See the RFC for
more context.

Depends on:
* npm/npm-registry-fetch#125
* npm/config#69
  • Loading branch information
jenseng committed Jul 12, 2022
1 parent 45a9bde commit 1b0b9ea
Show file tree
Hide file tree
Showing 6 changed files with 24 additions and 12 deletions.
3 changes: 2 additions & 1 deletion lib/commands/publish.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ const runScript = require('@npmcli/run-script')
const pacote = require('pacote')
const npa = require('npm-package-arg')
const npmFetch = require('npm-registry-fetch')
const hasCredentials = require('../utils/has-credentials.js')
const replaceInfo = require('../utils/replace-info.js')

const otplease = require('../utils/otplease.js')
Expand Down Expand Up @@ -101,7 +102,7 @@ class Publish extends BaseCommand {
const resolved = npa.resolve(manifest.name, manifest.version)
const registry = npmFetch.pickRegistry(resolved, opts)
const creds = this.npm.config.getCredentialsByURI(registry)
const noCreds = !creds.token && !creds.username
const noCreds = !hasCredentials(creds)
const outputRegistry = replaceInfo(registry)

if (noCreds) {
Expand Down
7 changes: 4 additions & 3 deletions lib/utils/config/definitions.js
Original file line number Diff line number Diff line change
Expand Up @@ -436,8 +436,8 @@ define('cert', {
cert="-----BEGIN CERTIFICATE-----\\nXXXX\\nXXXX\\n-----END CERTIFICATE-----"
\`\`\`
It is _not_ the path to a certificate file (and there is no "certfile"
option).
It is _not_ the path to a certificate file, though you can set a registry-scoped
"certfile" path like "//other-registry.tld/:certfile=/path/to/cert.pem".
`,
flatten,
})
Expand Down Expand Up @@ -1118,7 +1118,8 @@ define('key', {
key="-----BEGIN PRIVATE KEY-----\\nXXXX\\nXXXX\\n-----END PRIVATE KEY-----"
\`\`\`
It is _not_ the path to a key file (and there is no "keyfile" option).
It is _not_ the path to a key file, though you can set a registry-scoped
"keyfile" path like "//other-registry.tld/:keyfile=/path/to/key.pem".
`,
flatten,
})
Expand Down
5 changes: 3 additions & 2 deletions lib/utils/get-identity.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
const npmFetch = require('npm-registry-fetch')
const hasCredentials = require('./has-credentials.js')

module.exports = async (npm, opts) => {
const { registry } = opts
Expand All @@ -9,8 +10,8 @@ module.exports = async (npm, opts) => {
return creds.username
}

// No username, but we have a token; fetch the username from registry
if (creds.token) {
// No username, but we have other credentials; fetch the username from registry
if (hasCredentials(creds)) {
const registryData = await npmFetch.json('/-/whoami', { ...opts })
return registryData.username
}
Expand Down
5 changes: 5 additions & 0 deletions lib/utils/has-credentials.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
function hasCredentials (creds) {
return !!(creds.token || creds.username || creds.certfile && creds.keyfile)
}

module.exports = hasCredentials
8 changes: 5 additions & 3 deletions tap-snapshots/test/lib/utils/config/definitions.js.test.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -404,8 +404,9 @@ newlines replaced by the string "\\n". For example:
cert="-----BEGIN CERTIFICATE-----\\nXXXX\\nXXXX\\n-----END CERTIFICATE-----"
\`\`\`
It is _not_ the path to a certificate file (and there is no "certfile"
option).
It is _not_ the path to a certificate file, though you can set a
registry-scoped "certfile" path like
"//other-registry.tld/:certfile=/path/to/cert.pem".
`

exports[`test/lib/utils/config/definitions.js TAP > config description for ci-name 1`] = `
Expand Down Expand Up @@ -1016,7 +1017,8 @@ format with newlines replaced by the string "\\n". For example:
key="-----BEGIN PRIVATE KEY-----\\nXXXX\\nXXXX\\n-----END PRIVATE KEY-----"
\`\`\`
It is _not_ the path to a key file (and there is no "keyfile" option).
It is _not_ the path to a key file, though you can set a registry-scoped
"keyfile" path like "//other-registry.tld/:keyfile=/path/to/key.pem".
`

exports[`test/lib/utils/config/definitions.js TAP > config description for legacy-bundling 1`] = `
Expand Down
8 changes: 5 additions & 3 deletions tap-snapshots/test/lib/utils/config/describe-all.js.test.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -230,8 +230,9 @@ newlines replaced by the string "\\n". For example:
cert="-----BEGIN CERTIFICATE-----\\nXXXX\\nXXXX\\n-----END CERTIFICATE-----"
\`\`\`
It is _not_ the path to a certificate file (and there is no "certfile"
option).
It is _not_ the path to a certificate file, though you can set a
registry-scoped "certfile" path like
"//other-registry.tld/:certfile=/path/to/cert.pem".
<!-- automatically generated, do not edit manually -->
<!-- see lib/utils/config/definitions.js -->
Expand Down Expand Up @@ -819,7 +820,8 @@ format with newlines replaced by the string "\\n". For example:
key="-----BEGIN PRIVATE KEY-----\\nXXXX\\nXXXX\\n-----END PRIVATE KEY-----"
\`\`\`
It is _not_ the path to a key file (and there is no "keyfile" option).
It is _not_ the path to a key file, though you can set a registry-scoped
"keyfile" path like "//other-registry.tld/:keyfile=/path/to/key.pem".
<!-- automatically generated, do not edit manually -->
<!-- see lib/utils/config/definitions.js -->
Expand Down

0 comments on commit 1b0b9ea

Please sign in to comment.