Files
Lumotia/src-tauri/tests/config_hardening.rs

94 lines
2.8 KiB
Rust

use std::fs;
use std::path::Path;
use serde_json::Value;
fn manifest_dir() -> &'static Path {
Path::new(env!("CARGO_MANIFEST_DIR"))
}
fn read_json(path: impl AsRef<Path>) -> Value {
let raw = fs::read_to_string(path.as_ref()).expect("read json file");
serde_json::from_str(&raw).expect("valid json")
}
#[test]
fn csp_keeps_loopback_narrow() {
let conf = read_json(manifest_dir().join("tauri.conf.json"));
let csp = conf
.pointer("/app/security/csp")
.and_then(Value::as_str)
.expect("csp string");
let connect_src = csp
.split(';')
.map(str::trim)
.find(|directive| directive.starts_with("connect-src "))
.expect("connect-src directive");
assert!(connect_src.contains("http://127.0.0.1:*"));
assert!(connect_src.contains("ws://127.0.0.1:*"));
assert!(!connect_src.contains("http://localhost:*"));
assert!(!connect_src.contains("ws://localhost:*"));
}
#[test]
fn updater_is_signed_or_absent() {
let conf = read_json(manifest_dir().join("tauri.conf.json"));
if let Some(updater) = conf.pointer("/plugins/updater") {
let pubkey = updater
.get("pubkey")
.and_then(Value::as_str)
.unwrap_or_default();
assert!(
!pubkey.trim().is_empty(),
"updater config must not ship with an empty pubkey"
);
}
}
#[test]
fn secondary_windows_do_not_get_high_risk_plugin_permissions() {
let denied = [
"dialog:",
"autostart:",
"global-shortcut:",
"opener:",
"updater:",
];
let capability_dir = manifest_dir().join("capabilities");
for entry in fs::read_dir(capability_dir).expect("capabilities dir") {
let path = entry.expect("capability entry").path();
if path.extension().and_then(|ext| ext.to_str()) != Some("json") {
continue;
}
let capability = read_json(&path);
let windows = capability
.get("windows")
.and_then(Value::as_array)
.cloned()
.unwrap_or_default();
let applies_to_secondary = windows.iter().any(|window| {
matches!(
window.as_str(),
Some("tasks-float" | "transcript-viewer" | "transcription-preview")
)
});
if !applies_to_secondary {
continue;
}
let permissions = capability
.get("permissions")
.and_then(Value::as_array)
.cloned()
.unwrap_or_default();
for permission in permissions.iter().filter_map(Value::as_str) {
assert!(
!denied.iter().any(|prefix| permission.starts_with(prefix)),
"{} grants high-risk permission {permission} to a secondary window",
path.display()
);
}
}
}