From ecb118ff9d91e241d37bfcfd86d11b1a94a22e32 Mon Sep 17 00:00:00 2001 From: Satishchoudhary94 <148007944+Satishchoudhary94@users.noreply.github.com> Date: Sun, 18 Jan 2026 14:05:23 +0000 Subject: [PATCH] fix(#1440): Support NPM OIDC tokens by not exporting default NODE_AUTH_TOKEN This change addresses issue #1440 where NPM OIDC authentication was broken because the action was exporting a fake NODE_AUTH_TOKEN value by default. NPM OIDC requires NODE_AUTH_TOKEN to either be unset or empty for proper authentication. The fix only exports NODE_AUTH_TOKEN if it was explicitly set by the user, allowing OIDC to work while maintaining backward compatibility for users who explicitly provide tokens. BREAKING CHANGE: Users who rely on the fake default token should now explicitly provide NODE_AUTH_TOKEN in their workflows or use OIDC authentication. Fixes #1440 Related: https://github.com/actions/setup-node/issues/1440 --- __tests__/authutil.test.ts | 18 ++++++++++++++++++ dist/setup/index.js | 8 ++++++-- package-lock.json | 1 + src/authutil.ts | 11 ++++++----- 4 files changed, 31 insertions(+), 7 deletions(-) diff --git a/__tests__/authutil.test.ts b/__tests__/authutil.test.ts index d5f6c195f..b39c07a1d 100644 --- a/__tests__/authutil.test.ts +++ b/__tests__/authutil.test.ts @@ -118,6 +118,24 @@ describe('authutil tests', () => { expect(process.env.NODE_AUTH_TOKEN).toEqual('foobar'); }); + it('should not export NODE_AUTH_TOKEN if not set (OIDC support)', async () => { + // Clean NODE_AUTH_TOKEN from environment + delete process.env.NODE_AUTH_TOKEN; + await auth.configAuthentication('https://registry.npmjs.org/'); + expect(fs.statSync(rcFile)).toBeDefined(); + // NODE_AUTH_TOKEN should not be exported to environment if not initially set + // This allows OIDC authentication to work properly + const rc = readRcFile(rcFile); + expect(rc['registry']).toBe('https://registry.npmjs.org/'); + }); + + it('should export empty string NODE_AUTH_TOKEN if explicitly set to empty (OIDC support)', async () => { + process.env.NODE_AUTH_TOKEN = ''; + await auth.configAuthentication('https://registry.npmjs.org/'); + expect(fs.statSync(rcFile)).toBeDefined(); + expect(process.env.NODE_AUTH_TOKEN).toEqual(''); + }); + it('configAuthentication should overwrite non-scoped with non-scoped', async () => { fs.writeFileSync(rcFile, 'registry=NNN'); await auth.configAuthentication('https://registry.npmjs.org/'); diff --git a/dist/setup/index.js b/dist/setup/index.js index c59bedb4f..b39ea9a1b 100644 --- a/dist/setup/index.js +++ b/dist/setup/index.js @@ -53633,8 +53633,12 @@ function writeRegistryToFile(registryUrl, fileLocation) { newContents += `${authString}${os.EOL}${registryString}`; fs.writeFileSync(fileLocation, newContents); core.exportVariable('NPM_CONFIG_USERCONFIG', fileLocation); - // Export empty node_auth_token if didn't exist so npm doesn't complain about not being able to find it - core.exportVariable('NODE_AUTH_TOKEN', process.env.NODE_AUTH_TOKEN || 'XXXXX-XXXXX-XXXXX-XXXXX'); + // Only export NODE_AUTH_TOKEN if explicitly provided by user + // This is required to support NPM OIDC tokens which need NODE_AUTH_TOKEN to be unset + // See: https://github.com/actions/setup-node/issues/1440 + if (Object.prototype.hasOwnProperty.call(process.env, 'NODE_AUTH_TOKEN')) { + core.exportVariable('NODE_AUTH_TOKEN', process.env.NODE_AUTH_TOKEN); + } } diff --git a/package-lock.json b/package-lock.json index 97d9da250..47a5abe6d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -513,6 +513,7 @@ "integrity": "sha512-e7jT4DxYvIDLk1ZHmU/m/mB19rex9sv0c2ftBtjSBv+kVM/902eh0fINUzD7UwLLNR+jU585GxUJ8/EBfAM5fw==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@babel/code-frame": "^7.27.1", "@babel/generator": "^7.28.5", diff --git a/src/authutil.ts b/src/authutil.ts index e4b823bd5..f114ec1e9 100644 --- a/src/authutil.ts +++ b/src/authutil.ts @@ -46,9 +46,10 @@ function writeRegistryToFile(registryUrl: string, fileLocation: string) { newContents += `${authString}${os.EOL}${registryString}`; fs.writeFileSync(fileLocation, newContents); core.exportVariable('NPM_CONFIG_USERCONFIG', fileLocation); - // Export empty node_auth_token if didn't exist so npm doesn't complain about not being able to find it - core.exportVariable( - 'NODE_AUTH_TOKEN', - process.env.NODE_AUTH_TOKEN || 'XXXXX-XXXXX-XXXXX-XXXXX' - ); + // Only export NODE_AUTH_TOKEN if explicitly provided by user + // This is required to support NPM OIDC tokens which need NODE_AUTH_TOKEN to be unset + // See: https://github.com/actions/setup-node/issues/1440 + if (Object.prototype.hasOwnProperty.call(process.env, 'NODE_AUTH_TOKEN')) { + core.exportVariable('NODE_AUTH_TOKEN', process.env.NODE_AUTH_TOKEN); + } }