Skip to content

Commit f89b531

Browse files
authored
feat(node): support username and _password in .npmrc file (#24793)
Closes #23950
1 parent 1f2d48c commit f89b531

File tree

17 files changed

+135
-8
lines changed

17 files changed

+135
-8
lines changed

cli/npm/common.rs

Lines changed: 35 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,54 @@
11
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
22

3+
use base64::prelude::BASE64_STANDARD;
4+
use base64::Engine;
5+
use deno_core::anyhow::bail;
6+
use deno_core::error::AnyError;
37
use deno_npm::npm_rc::RegistryConfig;
48
use http::header;
59

610
// TODO(bartlomieju): support more auth methods besides token and basic auth
711
pub fn maybe_auth_header_for_npm_registry(
812
registry_config: &RegistryConfig,
9-
) -> Option<(header::HeaderName, header::HeaderValue)> {
13+
) -> Result<Option<(header::HeaderName, header::HeaderValue)>, AnyError> {
1014
if let Some(token) = registry_config.auth_token.as_ref() {
11-
return Some((
15+
return Ok(Some((
1216
header::AUTHORIZATION,
1317
header::HeaderValue::from_str(&format!("Bearer {}", token)).unwrap(),
14-
));
18+
)));
1519
}
1620

1721
if let Some(auth) = registry_config.auth.as_ref() {
18-
return Some((
22+
return Ok(Some((
1923
header::AUTHORIZATION,
2024
header::HeaderValue::from_str(&format!("Basic {}", auth)).unwrap(),
21-
));
25+
)));
2226
}
2327

24-
None
28+
let (username, password) = (
29+
registry_config.username.as_ref(),
30+
registry_config.password.as_ref(),
31+
);
32+
if (username.is_some() && password.is_none())
33+
|| (username.is_none() && password.is_some())
34+
{
35+
bail!("Both the username and password must be provided for basic auth")
36+
}
37+
38+
if username.is_some() && password.is_some() {
39+
return Ok(Some((
40+
header::AUTHORIZATION,
41+
header::HeaderValue::from_str(&format!(
42+
"Basic {}",
43+
BASE64_STANDARD.encode(&format!(
44+
"{}:{}",
45+
username.unwrap(),
46+
password.unwrap()
47+
))
48+
))
49+
.unwrap(),
50+
)));
51+
}
52+
53+
Ok(None)
2554
}

cli/npm/managed/cache/registry_info.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -192,7 +192,13 @@ impl RegistryInfoDownloader {
192192
let downloader = self.clone();
193193
let package_url = self.get_package_url(name);
194194
let registry_config = self.npmrc.get_registry_config(name);
195-
let maybe_auth_header = maybe_auth_header_for_npm_registry(registry_config);
195+
let maybe_auth_header =
196+
match maybe_auth_header_for_npm_registry(registry_config) {
197+
Ok(maybe_auth_header) => maybe_auth_header,
198+
Err(err) => {
199+
return std::future::ready(Err(Arc::new(err))).boxed_local()
200+
}
201+
};
196202
let guard = self.progress_bar.update(package_url.as_str());
197203
let name = name.to_string();
198204
async move {

cli/npm/managed/cache/tarball.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,7 @@ impl TarballCache {
167167
let tarball_uri = Url::parse(&dist.tarball)?;
168168
let maybe_registry_config =
169169
tarball_cache.npmrc.tarball_config(&tarball_uri);
170-
let maybe_auth_header = maybe_registry_config.and_then(|c| maybe_auth_header_for_npm_registry(c));
170+
let maybe_auth_header = maybe_registry_config.and_then(|c| maybe_auth_header_for_npm_registry(c).ok()?);
171171

172172
let guard = tarball_cache.progress_bar.update(&dist.tarball);
173173
let result = tarball_cache.http_client_provider
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
@denotest:registry=http://localhost:4261/
2+
//localhost:4261/:_password=land
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
{
2+
"envs": {
3+
"DENO_FUTURE": "1"
4+
},
5+
"tempDir": true,
6+
"steps": [{
7+
"args": "install",
8+
"output": "install.out",
9+
"exitCode": 1
10+
}]
11+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
[UNORDERED_START]
2+
error: Error getting response at http://localhost:4261/@denotest/basic for package "@denotest/basic": Both the username and password must be provided for basic auth
3+
[UNORDERED_END]
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"name": "npmrc_test",
3+
"version": "0.0.1",
4+
"dependencies": {
5+
"@denotest/basic": "^=1.0.0"
6+
}
7+
}
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
@denotest:registry=http://localhost:4261/
2+
//localhost:4261/:username=deno
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
{
2+
"envs": {
3+
"DENO_FUTURE": "1"
4+
},
5+
"tempDir": true,
6+
"steps": [{
7+
"args": "install",
8+
"output": "install.out",
9+
"exitCode": 1
10+
}]
11+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
[UNORDERED_START]
2+
error: Error getting response at http://localhost:4261/@denotest/basic for package "@denotest/basic": Both the username and password must be provided for basic auth
3+
[UNORDERED_END]

0 commit comments

Comments
 (0)