use std::process::Command;
fn ps_root() -> String {
let root = format!("{}/../..", env!("CARGO_MANIFEST_DIR"));
match std::env::var("PARSE_SERVER_ROOT") {
Ok(p) if std::path::Path::new(&p).is_absolute() => p,
Ok(p) => format!("{root}/{p}"),
Err(_) => format!("{root}/../parse-server"),
}
}
fn node(script: &str) -> String {
let out = Command::new("node")
.env_remove("NODE_OPTIONS")
.arg("-e")
.arg(script)
.output()
.expect("node must be on PATH; this test is #[ignore]d by default");
assert!(
out.status.success(),
"node failed: {}",
String::from_utf8_lossy(&out.stderr)
);
String::from_utf8_lossy(&out.stdout).trim().to_string()
}
fn bcryptjs() -> String {
format!(
"const bcrypt = require('{}/node_modules/bcryptjs');",
ps_root()
)
}
#[tokio::test]
#[ignore = "requires node and the upstream checkout; run via tools/test.sh"]
async fn rust_hash_verifies_in_parse_servers_bcrypt() {
let h = parse_rust_auth::password::hash("hunter2".into())
.await
.expect("hash");
let script = format!(
"{} console.log(bcrypt.compareSync('hunter2', {:?}) && !bcrypt.compareSync('wrong', {:?}));",
bcryptjs(),
h,
h
);
assert_eq!(
node(&script),
"true",
"parse-server could not verify a parse-rust hash: {h}"
);
}
#[tokio::test]
#[ignore = "requires node and the upstream checkout; run via tools/test.sh"]
async fn parse_servers_hash_verifies_in_rust() {
let h = node(&format!(
"{} console.log(bcrypt.hashSync('hunter2', 10));",
bcryptjs()
));
assert!(
parse_rust_auth::password::verify("hunter2".into(), h.clone()).await,
"parse-rust could not verify a parse-server hash: {h}"
);
assert!(!parse_rust_auth::password::verify("wrong".into(), h).await);
}
#[tokio::test]
#[ignore = "requires node and the upstream checkout; run via tools/test.sh"]
async fn the_prefix_question_is_answered_rather_than_assumed() {
let rust = parse_rust_auth::password::hash("x".into())
.await
.expect("hash");
let js = node(&format!(
"{} console.log(bcrypt.hashSync('x', 10));",
bcryptjs()
));
println!("rust prefix: {} js prefix: {}", &rust[..4], &js[..4]);
assert!(rust.starts_with("$2"), "unexpected rust format: {rust}");
assert!(js.starts_with("$2"), "unexpected js format: {js}");
}