1
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2025-01-19 12:16:17 -05:00
denoland-deno/resolvers/npm_cache/remote.rs
Leo Kettmeir ea30e188a8
refactor: update deno_core for error refactor (#26867)
Closes #26171

---------

Co-authored-by: David Sherret <dsherret@gmail.com>
2025-01-08 14:52:32 -08:00

69 lines
2.1 KiB
Rust

// Copyright 2018-2025 the Deno authors. MIT license.
use base64::prelude::BASE64_STANDARD;
use base64::Engine;
use deno_npm::npm_rc::RegistryConfig;
use http::header;
#[derive(Debug, thiserror::Error, deno_error::JsError)]
pub enum AuthHeaderForNpmRegistryError {
#[class(type)]
#[error("Both the username and password must be provided for basic auth")]
Both,
#[class(type)]
#[error("The password in npmrc is an invalid base64 string: {0}")]
Base64(base64::DecodeError),
}
// TODO(bartlomieju): support more auth methods besides token and basic auth
pub fn maybe_auth_header_for_npm_registry(
registry_config: &RegistryConfig,
) -> Result<
Option<(header::HeaderName, header::HeaderValue)>,
AuthHeaderForNpmRegistryError,
> {
if let Some(token) = registry_config.auth_token.as_ref() {
return Ok(Some((
header::AUTHORIZATION,
header::HeaderValue::from_str(&format!("Bearer {}", token)).unwrap(),
)));
}
if let Some(auth) = registry_config.auth.as_ref() {
return Ok(Some((
header::AUTHORIZATION,
header::HeaderValue::from_str(&format!("Basic {}", auth)).unwrap(),
)));
}
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())
{
return Err(AuthHeaderForNpmRegistryError::Both);
}
if username.is_some() && password.is_some() {
// The npm client does some double encoding when generating the
// bearer token value, see
// https://github.com/npm/cli/blob/780afc50e3a345feb1871a28e33fa48235bc3bd5/workspaces/config/lib/index.js#L846-L851
let pw_base64 = BASE64_STANDARD
.decode(password.unwrap())
.map_err(AuthHeaderForNpmRegistryError::Base64)?;
let bearer = BASE64_STANDARD.encode(format!(
"{}:{}",
username.unwrap(),
String::from_utf8_lossy(&pw_base64)
));
return Ok(Some((
header::AUTHORIZATION,
header::HeaderValue::from_str(&format!("Basic {}", bearer)).unwrap(),
)));
}
Ok(None)
}