mirror of
https://github.com/oven-sh/bun
synced 2026-02-02 15:08:46 +00:00
fix(install): match npmrc auth tokens by both host and path
When .npmrc contains multiple auth token entries for the same host but different paths, Bun was incorrectly using the last token for all registries because the matching logic only compared the host portion of URLs, ignoring the path. This fix ensures that auth tokens are matched by both host AND pathname, so that `//somehost.com/org1/npm/registry/:_authToken=jwt1` only applies to registry URLs with the exact path `/org1/npm/registry/`. Fixes #26350 Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -1306,7 +1306,9 @@ pub fn loadNpmrc(
|
||||
for (configs.items) |conf_item| {
|
||||
const conf_item_url = bun.URL.parse(conf_item.registry_url);
|
||||
|
||||
if (std.mem.eql(u8, bun.strings.withoutTrailingSlash(default_registry_url.host), bun.strings.withoutTrailingSlash(conf_item_url.host))) {
|
||||
if (std.mem.eql(u8, bun.strings.withoutTrailingSlash(default_registry_url.host), bun.strings.withoutTrailingSlash(conf_item_url.host)) and
|
||||
std.mem.eql(u8, bun.strings.withoutTrailingSlash(default_registry_url.pathname), bun.strings.withoutTrailingSlash(conf_item_url.pathname)))
|
||||
{
|
||||
// Apply config to default registry
|
||||
const v: *bun.schema.api.NpmRegistry = brk: {
|
||||
if (install.default_registry) |*r| break :brk r;
|
||||
@@ -1343,7 +1345,9 @@ pub fn loadNpmrc(
|
||||
for (registry_map.scopes.keys(), registry_map.scopes.values()) |*k, *v| {
|
||||
const url = url_map.get(k.*) orelse unreachable;
|
||||
|
||||
if (std.mem.eql(u8, bun.strings.withoutTrailingSlash(url.host), bun.strings.withoutTrailingSlash(conf_item_url.host))) {
|
||||
if (std.mem.eql(u8, bun.strings.withoutTrailingSlash(url.host), bun.strings.withoutTrailingSlash(conf_item_url.host)) and
|
||||
std.mem.eql(u8, bun.strings.withoutTrailingSlash(url.pathname), bun.strings.withoutTrailingSlash(conf_item_url.pathname)))
|
||||
{
|
||||
if (conf_item_url.hostname.len > 0) {
|
||||
if (!std.mem.eql(u8, bun.strings.withoutTrailingSlash(url.hostname), bun.strings.withoutTrailingSlash(conf_item_url.hostname))) {
|
||||
continue;
|
||||
|
||||
@@ -464,4 +464,33 @@ ${Object.keys(opts)
|
||||
expect(result.default_registry_email).toEqual("test@example.com");
|
||||
},
|
||||
);
|
||||
|
||||
test("applies auth tokens to default registry correctly - same host different paths", () => {
|
||||
// Regression test for https://github.com/oven-sh/bun/issues/26350
|
||||
// When multiple auth tokens exist for the same host but different paths,
|
||||
// Bun should match the token by both host AND path, not just host.
|
||||
const ini = `
|
||||
registry=https://somehost.com/org1/npm/registry/
|
||||
//somehost.com/org1/npm/registry/:_authToken=jwt1
|
||||
//somehost.com/org2/npm/registry/:_authToken=jwt2
|
||||
//somehost.com/org3/npm/registry/:_authToken=jwt3
|
||||
`;
|
||||
const result = loadNpmrc(ini);
|
||||
expect(result.default_registry_url).toEqual("https://somehost.com/org1/npm/registry/");
|
||||
expect(result.default_registry_token).toBe("jwt1");
|
||||
});
|
||||
|
||||
test("auth token not applied when paths don't match - same host", () => {
|
||||
// Regression test for https://github.com/oven-sh/bun/issues/26350
|
||||
// When auth tokens exist for a different path on the same host,
|
||||
// they should not be applied to the default registry.
|
||||
const ini = `
|
||||
registry=https://somehost.com/org1/npm/registry/
|
||||
//somehost.com/org2/npm/registry/:_authToken=jwt2
|
||||
`;
|
||||
const result = loadNpmrc(ini);
|
||||
expect(result.default_registry_url).toEqual("https://somehost.com/org1/npm/registry/");
|
||||
// Should be empty since there's no matching token for /org1/npm/registry/
|
||||
expect(result.default_registry_token).toBe("");
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user