Complete desktop parity and security audit (#42)

This commit is contained in:
2026-08-10 20:38:28 +02:00
parent 4a54bf7b6a
commit 40b15a9713
5 changed files with 340 additions and 36 deletions

View File

@@ -852,14 +852,18 @@ fn main() -> iced::Result {
.title(ironstorage::PRODUCT_NAME)
.subscription(App::subscription)
.exit_on_close_request(false)
.window(window::Settings {
size: Size::new(1_080.0, 720.0),
min_size: Some(Size::new(720.0, 480.0)),
..window::Settings::default()
})
.window(window_settings())
.run()
}
fn window_settings() -> window::Settings {
window::Settings {
size: Size::new(1_080.0, 720.0),
min_size: Some(Size::new(720.0, 480.0)),
..window::Settings::default()
}
}
impl App {
fn new() -> (Self, Task<Message>) {
let mut app = Self {
@@ -3345,11 +3349,8 @@ impl App {
.min_size(220)
.on_resize(8, Message::PaneResized);
let shortcut = if cfg!(target_os = "macos") {
"⌘K"
} else {
"Ctrl+K"
};
let shortcut = action::shortcut_label(UiAction::CommandPalette)
.expect("the command palette has a registered shortcut");
let command_input = text_input(
&format!("Search commands ({shortcut})"),
self.palette.query(),
@@ -5034,6 +5035,89 @@ mod tests {
use super::*;
#[test]
fn desktop_coverage_matrix_contains_every_registered_action() {
let matrix = include_str!("../../../docs/desktop-audit.md");
for spec in action::ACTIONS {
assert!(
matrix.contains(&format!("`{}`", spec.action.id())),
"desktop parity matrix is missing {}",
spec.action.id()
);
}
for required_surface in [
"Base pass",
"Pass OTP",
"Embedded Git",
"Configuration and lock",
"macOS",
"Linux",
"Windows",
] {
assert!(
matrix.contains(required_surface),
"missing {required_surface}"
);
}
}
#[test]
fn production_desktop_sources_preserve_security_and_architecture_boundaries() {
let sources = [
("action.rs", include_str!("action.rs")),
("editor.rs", include_str!("editor.rs")),
("folder_picker.rs", include_str!("folder_picker.rs")),
("main.rs", include_str!("main.rs")),
("native_menu.rs", include_str!("native_menu.rs")),
("navigation.rs", include_str!("navigation.rs")),
("palette.rs", include_str!("palette.rs")),
];
for (name, source) in sources {
let production = source
.split("#[cfg(test)]\nmod tests")
.next()
.unwrap_or(source);
let forbidden_tokens = [
["std::", "process"].concat(),
["process", "::Command"].concat(),
["Command", "::new("].concat(),
["Repository", "::open"].concat(),
["GitRepository", "::"].concat(),
["OtpUri", "::parse"].concat(),
["qrcode", "::QrCode"].concat(),
["fs::", "write"].concat(),
["File", "::create"].concat(),
["OpenOptions", "::new"].concat(),
["println", "!("].concat(),
["eprintln", "!("].concat(),
["dbg", "!("].concat(),
["log", "::info"].concat(),
["log", "::debug"].concat(),
["log", "::error"].concat(),
["tracing", "::info"].concat(),
["tracing", "::debug"].concat(),
["tracing", "::error"].concat(),
["http", "://"].concat(),
["unsafe", " {"].concat(),
];
for forbidden in &forbidden_tokens {
assert!(
!production.contains(forbidden),
"{name} crosses the desktop architecture boundary with {forbidden}"
);
}
}
}
#[test]
fn window_contract_keeps_both_scrollable_panes_usable_at_narrow_size() {
let settings = window_settings();
assert_eq!(settings.size, Size::new(1_080.0, 720.0));
assert_eq!(settings.min_size, Some(Size::new(720.0, 480.0)));
let app = test_app(None);
let _view = app.view();
}
#[derive(Clone, Default)]
struct ManualClock(Arc<Mutex<Duration>>);