#[cfg(feature = "nkeys")]
use nkeys::KeyPair;
#[cfg(feature = "nkeys")]
use regex::Regex;
#[cfg(feature = "nkeys")]
use std::sync::LazyLock;
#[cfg(feature = "nkeys")]
use std::{io, path::Path};
#[cfg(feature = "nkeys")]
pub(crate) async fn load_creds(path: &Path) -> io::Result<String> {
tokio::fs::read_to_string(path).await.map_err(|err| {
io::Error::other(format!("loading creds file '{}': {}", path.display(), err))
})
}
#[cfg(feature = "nkeys")]
pub(crate) fn parse_jwt_and_key_from_creds(contents: &str) -> io::Result<(&str, KeyPair)> {
let jwt = parse_decorated_jwt(contents).ok_or_else(|| {
io::Error::new(
io::ErrorKind::InvalidData,
"cannot parse user JWT from the credentials file",
)
})?;
let nkey = parse_decorated_nkey(contents).ok_or_else(|| {
io::Error::new(
io::ErrorKind::InvalidData,
"cannot parse nkey from the credentials file",
)
})?;
let kp =
KeyPair::from_seed(nkey).map_err(|err| io::Error::new(io::ErrorKind::InvalidData, err))?;
Ok((jwt, kp))
}
#[cfg(feature = "nkeys")]
static USER_CONFIG_RE: LazyLock<Regex> = LazyLock::new(|| {
Regex::new(r"\s*(?:(?:[-]{3,}.*[-]{3,}\r?\n)([\w\-.=]+)(?:\r?\n[-]{3,}.*[-]{3,}\r?\n))")
.unwrap()
});
#[cfg(feature = "nkeys")]
fn parse_decorated_jwt(contents: &str) -> Option<&str> {
let capture = USER_CONFIG_RE.captures_iter(contents).next()?;
Some(capture.get(1)?.as_str())
}
#[cfg(feature = "nkeys")]
fn parse_decorated_nkey(contents: &str) -> Option<&str> {
let capture = USER_CONFIG_RE.captures_iter(contents).nth(1)?;
Some(capture.get(1)?.as_str())
}