summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAsher Gomez <ashersaupingomez@gmail.com>2024-08-14 18:53:15 +0200
committerGitHub <noreply@github.com>2024-08-14 18:53:15 +0200
commitf89b5311492377a3ac18d756dc8c8a309e2c9e8a (patch)
tree68fc92eb556eb72cf75d4f3dd8ff424e283853c2
parent1f2d48cd975b719f0248e471f3b503cb01398dfb (diff)
feat(node): support `username` and `_password` in `.npmrc` file (#24793)
Closes #23950
-rw-r--r--cli/npm/common.rs41
-rw-r--r--cli/npm/managed/cache/registry_info.rs8
-rw-r--r--cli/npm/managed/cache/tarball.rs2
-rw-r--r--tests/specs/npm/npmrc_password_no_username/.npmrc2
-rw-r--r--tests/specs/npm/npmrc_password_no_username/__test__.jsonc11
-rw-r--r--tests/specs/npm/npmrc_password_no_username/install.out3
-rw-r--r--tests/specs/npm/npmrc_password_no_username/package.json7
-rw-r--r--tests/specs/npm/npmrc_username_no_password/.npmrc2
-rw-r--r--tests/specs/npm/npmrc_username_no_password/__test__.jsonc11
-rw-r--r--tests/specs/npm/npmrc_username_no_password/install.out3
-rw-r--r--tests/specs/npm/npmrc_username_no_password/package.json7
-rw-r--r--tests/specs/npm/npmrc_username_password/.npmrc6
-rw-r--r--tests/specs/npm/npmrc_username_password/__test__.jsonc13
-rw-r--r--tests/specs/npm/npmrc_username_password/install.out8
-rw-r--r--tests/specs/npm/npmrc_username_password/main.js8
-rw-r--r--tests/specs/npm/npmrc_username_password/main.out3
-rw-r--r--tests/specs/npm/npmrc_username_password/package.json8
17 files changed, 135 insertions, 8 deletions
diff --git a/cli/npm/common.rs b/cli/npm/common.rs
index 34835216c..a3a828e74 100644
--- a/cli/npm/common.rs
+++ b/cli/npm/common.rs
@@ -1,25 +1,54 @@
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
+use base64::prelude::BASE64_STANDARD;
+use base64::Engine;
+use deno_core::anyhow::bail;
+use deno_core::error::AnyError;
use deno_npm::npm_rc::RegistryConfig;
use http::header;
// TODO(bartlomieju): support more auth methods besides token and basic auth
pub fn maybe_auth_header_for_npm_registry(
registry_config: &RegistryConfig,
-) -> Option<(header::HeaderName, header::HeaderValue)> {
+) -> Result<Option<(header::HeaderName, header::HeaderValue)>, AnyError> {
if let Some(token) = registry_config.auth_token.as_ref() {
- return Some((
+ return Ok(Some((
header::AUTHORIZATION,
header::HeaderValue::from_str(&format!("Bearer {}", token)).unwrap(),
- ));
+ )));
}
if let Some(auth) = registry_config.auth.as_ref() {
- return Some((
+ return Ok(Some((
header::AUTHORIZATION,
header::HeaderValue::from_str(&format!("Basic {}", auth)).unwrap(),
- ));
+ )));
}
- None
+ let (username, password) = (
+ registry_config.username.as_ref(),
+ registry_config.password.as_ref(),
+ );
+ if (username.is_some() && password.is_none())
+ || (username.is_none() && password.is_some())
+ {
+ bail!("Both the username and password must be provided for basic auth")
+ }
+
+ if username.is_some() && password.is_some() {
+ return Ok(Some((
+ header::AUTHORIZATION,
+ header::HeaderValue::from_str(&format!(
+ "Basic {}",
+ BASE64_STANDARD.encode(&format!(
+ "{}:{}",
+ username.unwrap(),
+ password.unwrap()
+ ))
+ ))
+ .unwrap(),
+ )));
+ }
+
+ Ok(None)
}
diff --git a/cli/npm/managed/cache/registry_info.rs b/cli/npm/managed/cache/registry_info.rs
index d7675a34f..28b19373e 100644
--- a/cli/npm/managed/cache/registry_info.rs
+++ b/cli/npm/managed/cache/registry_info.rs
@@ -192,7 +192,13 @@ impl RegistryInfoDownloader {
let downloader = self.clone();
let package_url = self.get_package_url(name);
let registry_config = self.npmrc.get_registry_config(name);
- let maybe_auth_header = maybe_auth_header_for_npm_registry(registry_config);
+ let maybe_auth_header =
+ match maybe_auth_header_for_npm_registry(registry_config) {
+ Ok(maybe_auth_header) => maybe_auth_header,
+ Err(err) => {
+ return std::future::ready(Err(Arc::new(err))).boxed_local()
+ }
+ };
let guard = self.progress_bar.update(package_url.as_str());
let name = name.to_string();
async move {
diff --git a/cli/npm/managed/cache/tarball.rs b/cli/npm/managed/cache/tarball.rs
index eec890bed..4bcee38ea 100644
--- a/cli/npm/managed/cache/tarball.rs
+++ b/cli/npm/managed/cache/tarball.rs
@@ -167,7 +167,7 @@ impl TarballCache {
let tarball_uri = Url::parse(&dist.tarball)?;
let maybe_registry_config =
tarball_cache.npmrc.tarball_config(&tarball_uri);
- let maybe_auth_header = maybe_registry_config.and_then(|c| maybe_auth_header_for_npm_registry(c));
+ let maybe_auth_header = maybe_registry_config.and_then(|c| maybe_auth_header_for_npm_registry(c).ok()?);
let guard = tarball_cache.progress_bar.update(&dist.tarball);
let result = tarball_cache.http_client_provider
diff --git a/tests/specs/npm/npmrc_password_no_username/.npmrc b/tests/specs/npm/npmrc_password_no_username/.npmrc
new file mode 100644
index 000000000..e2d7b09e2
--- /dev/null
+++ b/tests/specs/npm/npmrc_password_no_username/.npmrc
@@ -0,0 +1,2 @@
+@denotest:registry=http://localhost:4261/
+//localhost:4261/:_password=land
diff --git a/tests/specs/npm/npmrc_password_no_username/__test__.jsonc b/tests/specs/npm/npmrc_password_no_username/__test__.jsonc
new file mode 100644
index 000000000..a36537cb7
--- /dev/null
+++ b/tests/specs/npm/npmrc_password_no_username/__test__.jsonc
@@ -0,0 +1,11 @@
+{
+ "envs": {
+ "DENO_FUTURE": "1"
+ },
+ "tempDir": true,
+ "steps": [{
+ "args": "install",
+ "output": "install.out",
+ "exitCode": 1
+ }]
+}
diff --git a/tests/specs/npm/npmrc_password_no_username/install.out b/tests/specs/npm/npmrc_password_no_username/install.out
new file mode 100644
index 000000000..d49a2ba0d
--- /dev/null
+++ b/tests/specs/npm/npmrc_password_no_username/install.out
@@ -0,0 +1,3 @@
+[UNORDERED_START]
+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
+[UNORDERED_END]
diff --git a/tests/specs/npm/npmrc_password_no_username/package.json b/tests/specs/npm/npmrc_password_no_username/package.json
new file mode 100644
index 000000000..f3757170a
--- /dev/null
+++ b/tests/specs/npm/npmrc_password_no_username/package.json
@@ -0,0 +1,7 @@
+{
+ "name": "npmrc_test",
+ "version": "0.0.1",
+ "dependencies": {
+ "@denotest/basic": "^=1.0.0"
+ }
+}
diff --git a/tests/specs/npm/npmrc_username_no_password/.npmrc b/tests/specs/npm/npmrc_username_no_password/.npmrc
new file mode 100644
index 000000000..e7f4e6064
--- /dev/null
+++ b/tests/specs/npm/npmrc_username_no_password/.npmrc
@@ -0,0 +1,2 @@
+@denotest:registry=http://localhost:4261/
+//localhost:4261/:username=deno \ No newline at end of file
diff --git a/tests/specs/npm/npmrc_username_no_password/__test__.jsonc b/tests/specs/npm/npmrc_username_no_password/__test__.jsonc
new file mode 100644
index 000000000..a36537cb7
--- /dev/null
+++ b/tests/specs/npm/npmrc_username_no_password/__test__.jsonc
@@ -0,0 +1,11 @@
+{
+ "envs": {
+ "DENO_FUTURE": "1"
+ },
+ "tempDir": true,
+ "steps": [{
+ "args": "install",
+ "output": "install.out",
+ "exitCode": 1
+ }]
+}
diff --git a/tests/specs/npm/npmrc_username_no_password/install.out b/tests/specs/npm/npmrc_username_no_password/install.out
new file mode 100644
index 000000000..d49a2ba0d
--- /dev/null
+++ b/tests/specs/npm/npmrc_username_no_password/install.out
@@ -0,0 +1,3 @@
+[UNORDERED_START]
+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
+[UNORDERED_END]
diff --git a/tests/specs/npm/npmrc_username_no_password/package.json b/tests/specs/npm/npmrc_username_no_password/package.json
new file mode 100644
index 000000000..f3757170a
--- /dev/null
+++ b/tests/specs/npm/npmrc_username_no_password/package.json
@@ -0,0 +1,7 @@
+{
+ "name": "npmrc_test",
+ "version": "0.0.1",
+ "dependencies": {
+ "@denotest/basic": "^=1.0.0"
+ }
+}
diff --git a/tests/specs/npm/npmrc_username_password/.npmrc b/tests/specs/npm/npmrc_username_password/.npmrc
new file mode 100644
index 000000000..c318678ae
--- /dev/null
+++ b/tests/specs/npm/npmrc_username_password/.npmrc
@@ -0,0 +1,6 @@
+@denotest:registry=http://localhost:4261/
+//localhost:4261/:username=deno
+//localhost:4261/:_password=land
+@denotest2:registry=http://localhost:4262/
+//localhost:4262/:username=deno
+//localhost:4262/:_password=land2
diff --git a/tests/specs/npm/npmrc_username_password/__test__.jsonc b/tests/specs/npm/npmrc_username_password/__test__.jsonc
new file mode 100644
index 000000000..44298ed2f
--- /dev/null
+++ b/tests/specs/npm/npmrc_username_password/__test__.jsonc
@@ -0,0 +1,13 @@
+{
+ "envs": {
+ "DENO_FUTURE": "1"
+ },
+ "tempDir": true,
+ "steps": [{
+ "args": "install",
+ "output": "install.out"
+ }, {
+ "args": "run -A main.js",
+ "output": "main.out"
+ }]
+}
diff --git a/tests/specs/npm/npmrc_username_password/install.out b/tests/specs/npm/npmrc_username_password/install.out
new file mode 100644
index 000000000..30643527e
--- /dev/null
+++ b/tests/specs/npm/npmrc_username_password/install.out
@@ -0,0 +1,8 @@
+[UNORDERED_START]
+Download http://localhost:4261/@denotest/basic
+Download http://localhost:4262/@denotest2/basic
+Download http://localhost:4261/@denotest/basic/1.0.0.tgz
+Download http://localhost:4262/@denotest2/basic/1.0.0.tgz
+Initialize @denotest2/basic@1.0.0
+Initialize @denotest/basic@1.0.0
+[UNORDERED_END]
diff --git a/tests/specs/npm/npmrc_username_password/main.js b/tests/specs/npm/npmrc_username_password/main.js
new file mode 100644
index 000000000..66b393636
--- /dev/null
+++ b/tests/specs/npm/npmrc_username_password/main.js
@@ -0,0 +1,8 @@
+import { getValue, setValue } from "@denotest/basic";
+import * as test from "@denotest2/basic";
+
+console.log(getValue());
+setValue(42);
+console.log(getValue());
+
+console.log(test.getValue());
diff --git a/tests/specs/npm/npmrc_username_password/main.out b/tests/specs/npm/npmrc_username_password/main.out
new file mode 100644
index 000000000..bbe210bdb
--- /dev/null
+++ b/tests/specs/npm/npmrc_username_password/main.out
@@ -0,0 +1,3 @@
+0
+42
+0
diff --git a/tests/specs/npm/npmrc_username_password/package.json b/tests/specs/npm/npmrc_username_password/package.json
new file mode 100644
index 000000000..13e305931
--- /dev/null
+++ b/tests/specs/npm/npmrc_username_password/package.json
@@ -0,0 +1,8 @@
+{
+ "name": "npmrc_test",
+ "version": "0.0.1",
+ "dependencies": {
+ "@denotest/basic": "^=1.0.0",
+ "@denotest2/basic": "1.0.0"
+ }
+}