Skip to content

Commit 604c745

Browse files
authored
fix: oidc idp token as header, exchange endpoint change (#8370)
1 parent aa16235 commit 604c745

File tree

2 files changed

+20
-12
lines changed

2 files changed

+20
-12
lines changed

lib/utils/oidc.js

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ const { log } = require('proc-log')
22
const npmFetch = require('npm-registry-fetch')
33
const ciInfo = require('ci-info')
44
const fetch = require('make-fetch-happen')
5+
const npa = require('npm-package-arg')
56

67
/**
78
* Handles OpenID Connect (OIDC) token retrieval and exchange for CI environments.
@@ -103,21 +104,28 @@ async function oidc ({ packageName, registry, opts, config }) {
103104
return undefined
104105
}
105106

106-
const response = await npmFetch.json(new URL('/-/npm/v1/oidc/token/exchange', registry), {
107-
...opts,
107+
const parsedRegistry = new URL(registry)
108+
const regKey = `//${parsedRegistry.host}${parsedRegistry.pathname}`
109+
const authTokenKey = `${regKey}:_authToken`
110+
111+
const escapedPackageName = npa(packageName).escapedName
112+
const response = await npmFetch.json(new URL(`/-/npm/v1/oidc/token/exchange/package/${escapedPackageName}`, registry), {
113+
...{
114+
...opts,
115+
[authTokenKey]: idToken, // Use the idToken as the auth token for the request
116+
},
108117
method: 'POST',
109-
body: {
110-
package_name: packageName,
111-
id_token: idToken,
118+
headers: {
119+
...opts.headers,
120+
'Content-Type': 'application/json',
121+
// this will not work because the existing auth token will replace it.
122+
// authorization: `Bearer ${idToken}`,
112123
},
113124
})
114125

115126
if (!response?.token) {
116127
throw new Error('OIDC token exchange failure: missing token in response body')
117128
}
118-
const parsedRegistry = new URL(registry)
119-
const regKey = `//${parsedRegistry.host}${parsedRegistry.pathname}`
120-
const authTokenKey = `${regKey}:_authToken`
121129
/*
122130
* The "opts" object is a clone of npm.flatOptions and is passed through the `publish` command,
123131
* eventually reaching `otplease`. To ensure the token is accessible during the publishing process,

mock-registry/lib/index.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -632,10 +632,10 @@ class MockRegistry {
632632
}
633633

634634
mockOidcTokenExchange ({ packageName, idToken, token, statusCode = 200 } = {}) {
635-
this.nock.post(this.fullPath('/-/npm/v1/oidc/token/exchange'), body => {
636-
return body.package_name === packageName && body.id_token === idToken
637-
}).reply(statusCode, statusCode !== 500 ? { token: token } : { message: 'Internal Server Error' })
638-
return { token }
635+
const encodedPackageName = npa(packageName).escapedName
636+
this.nock.post(this.fullPath(`/-/npm/v1/oidc/token/exchange/package/${encodedPackageName}`))
637+
.matchHeader('authorization', `Bearer ${idToken}`)
638+
.reply(statusCode, statusCode !== 500 ? { token } : { message: 'Internal Server Error' })
639639
}
640640
}
641641

0 commit comments

Comments
 (0)