use nkeys::KeyPair;
use once_cell::sync::Lazy;
use regex::Regex;
use std::{io, path::Path};
pub(crate) async fn load_creds(path: &Path) -> io::Result<String> {
tokio::fs::read_to_string(path).await.map_err(|err| {
io::Error::new(
io::ErrorKind::Other,
format!("loading creds file '{}': {}", path.display(), err),
)
})
}
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))
}
static USER_CONFIG_RE: Lazy<Regex> = Lazy::new(|| {
Regex::new(r"\s*(?:(?:[-]{3,}.*[-]{3,}\r?\n)([\w\-.=]+)(?:\r?\n[-]{3,}.*[-]{3,}\r?\n))")
.unwrap()
});
fn parse_decorated_jwt(contents: &str) -> Option<&str> {
let capture = USER_CONFIG_RE.captures_iter(contents).next()?;
Some(capture.get(1)?.as_str())
}
fn parse_decorated_nkey(contents: &str) -> Option<&str> {
let capture = USER_CONFIG_RE.captures_iter(contents).nth(1)?;
Some(capture.get(1)?.as_str())
}