v0.2.6-pre.012

This commit is contained in:
2026-08-21 16:22:16 +02:00
parent 8ba554306a
commit ecbd6b746d
21 changed files with 634 additions and 94 deletions

View File

@@ -1,5 +1,5 @@
// file: crates/ksp-app-wallet-desk/tests/desktop_contract.rs
// version: 12
// version: 13
//! Desktop build, shell and Config-status contract audits for Wallet Desk.
@@ -302,5 +302,32 @@ fn pre_011_strong_view_administration_is_owner_only_and_refreshes_safe_status()
assert!(main.contains("runStrongViewDisable"));
assert!(main.contains("runStrongViewRecreate"));
assert!(main.contains("applyViewSecurityStatus"));
assert!(main.contains("pre.011-strong-view-administration"));
assert!(main.contains("bindStrongViewSecurityActions"));
}
#[test]
fn pre_012_owner_export_uses_rust_native_save_picker_and_wallet_file_adapter() {
let root = app_root();
let state = read_text(root.join("src/app_state.rs").as_path());
let export = read_text(root.join("src/wallet_export.rs").as_path());
let transfer = read_text(root.join("src/wallet_transfer.rs").as_path());
let tauri = read_text(root.join("src/tauri.rs").as_path());
let html = read_text(root.join("frontend/main.html").as_path());
let main = read_text(root.join("frontend/ts/main.ts").as_path());
assert!(export.contains("WalletExportRequestDto"));
assert!(export.contains("WalletExportResultDto"));
assert!(transfer.contains("WalletTransferFormatDto"));
assert!(transfer.contains("solana_cli_json"));
assert!(transfer.contains("solana_keypair_base58"));
assert!(state.contains("wallet_export_picker_filename"));
assert!(state.contains("begin_owner_operation(\"keypair_export\")"));
assert!(state.contains("owner.export_transfer_file"));
assert!(tauri.contains("blocking_save_file"));
assert!(tauri.contains("export_wallet_transfer"));
assert!(html.contains("id=\"walletExportFormat\""));
assert!(html.contains("id=\"exportWalletKeypair\""));
assert!(html.contains("id=\"exportWalletKeypairModal\""));
assert!(main.contains("bindWalletExportActions"));
assert!(main.contains("export_wallet_transfer"));
assert!(main.contains("pre.012-owner-transfer-export"));
}

View File

@@ -1,5 +1,5 @@
// file: crates/ksp-app-wallet-desk/tests/desktop_security.rs
// version: 12
// version: 13
//! Static desktop security contracts for the Wallet Desk pre.002 shell.
@@ -181,7 +181,7 @@ fn owner_metadata_values_are_request_only_and_state_conflict_forces_reauthorizat
assert!(!main.contains("frontendTrace(\"main\", request.text"));
assert!(!main.contains("frontendDebug(\"main\", request.alias"));
assert!(!main.contains("window.confirm"));
assert!(main.contains("new Modal(modalElement)"));
assert!(main.contains("deleteNoteModal = new Modal(modalElement)"));
}
#[test]
@@ -262,3 +262,63 @@ fn strong_view_administration_is_owner_only_uses_bootstrap_modals_and_returns_no
assert!(!main.contains("frontendDebug(\"main\", request.password"));
assert!(!main.contains("frontendTrace(\"main\", request.password"));
}
#[test]
fn owner_export_never_projects_key_material_or_full_destination_path_to_frontend() {
let root = app_root();
let export = read_text(root.join("src/wallet_export.rs").as_path());
let state = read_text(root.join("src/app_state.rs").as_path());
let tauri = read_text(root.join("src/tauri.rs").as_path());
let main = read_text(root.join("frontend/ts/main.ts").as_path());
let request = export.split("pub(crate) struct WalletExportRequestDto").nth(1);
assert!(request.is_some());
let request_fields = request
.unwrap_or_default()
.split("}\n")
.next()
.unwrap_or_default()
.lines()
.filter(|line| return line.trim_start().starts_with("pub(crate) "))
.collect::<std::vec::Vec<_>>()
.join("\n");
assert!(request_fields.contains("format"));
assert!(!export.contains("#[derive(Clone, serde::Deserialize"));
assert!(!export.contains("#[derive(Debug, serde::Deserialize"));
assert!(!request_fields.contains("path"));
assert!(!request_fields.contains("password"));
assert!(!request_fields.contains("secret"));
let result = export.split("pub(crate) struct WalletExportResultDto").nth(1);
assert!(result.is_some());
let result_fields = result
.unwrap_or_default()
.split("}\n")
.next()
.unwrap_or_default()
.lines()
.filter(|line| return line.trim_start().starts_with("pub(crate) "))
.collect::<std::vec::Vec<_>>()
.join("\n");
assert!(result_fields.contains("destination_name"));
assert!(result_fields.contains("format"));
assert!(result_fields.contains("wallet_id"));
assert!(!result_fields.contains("path"));
assert!(!result_fields.contains("pubkey"));
assert!(!result_fields.contains("password"));
assert!(!result_fields.contains("secret"));
assert!(!result_fields.contains("content"));
assert!(!result_fields.contains("bytes"));
assert!(state.contains("owner.export_transfer_file"));
assert!(!state.contains("owner.export_transfer(format"));
let command_start = tauri.find("async fn export_wallet_transfer");
assert!(command_start.is_some());
let command = &tauri[command_start.unwrap_or_default()..];
let command = command.split("#[tauri::command]").next().unwrap_or_default();
assert!(command.contains("WalletExportRequestDto"));
assert!(command.contains("WalletExportResultDto"));
assert!(!main.contains("navigator.clipboard"));
assert!(!main.contains("destinationPath"));
assert!(!main.contains("destination_path"));
assert!(!main.contains("keypairBytes"));
assert!(!main.contains("secretKey"));
assert!(main.contains("exportWalletModal = new Modal(modalElement)"));
}