2026-04-13 07:58:20 +00:00
|
|
|
mod commands;
|
2026-04-13 07:48:27 +00:00
|
|
|
mod db;
|
|
|
|
|
mod error;
|
2026-04-13 07:54:52 +00:00
|
|
|
mod models;
|
2026-04-13 12:23:23 +00:00
|
|
|
mod services;
|
2026-04-13 07:48:27 +00:00
|
|
|
|
2026-04-13 12:20:45 +00:00
|
|
|
use std::sync::{Arc, Mutex};
|
2026-04-13 07:48:27 +00:00
|
|
|
use tauri::Manager;
|
|
|
|
|
|
|
|
|
|
pub struct AppState {
|
2026-04-13 12:20:45 +00:00
|
|
|
pub db: Arc<Mutex<rusqlite::Connection>>,
|
|
|
|
|
pub encryption_key: [u8; 32],
|
|
|
|
|
pub http_client: reqwest::Client,
|
2026-04-13 07:48:27 +00:00
|
|
|
}
|
|
|
|
|
|
2026-04-13 07:31:24 +00:00
|
|
|
#[cfg_attr(mobile, tauri::mobile_entry_point)]
|
|
|
|
|
pub fn run() {
|
|
|
|
|
tauri::Builder::default()
|
2026-04-13 07:58:20 +00:00
|
|
|
.plugin(tauri_plugin_dialog::init())
|
2026-04-13 07:48:27 +00:00
|
|
|
.setup(|app| {
|
|
|
|
|
let db_dir = app.path().app_data_dir()?;
|
|
|
|
|
std::fs::create_dir_all(&db_dir)?;
|
2026-04-13 12:20:45 +00:00
|
|
|
|
2026-04-13 07:48:27 +00:00
|
|
|
let db_path = db_dir.join("orchai.db");
|
|
|
|
|
let conn = db::init(&db_path).expect("Failed to initialize database");
|
2026-04-13 12:20:45 +00:00
|
|
|
|
|
|
|
|
let key_path = db_dir.join("orchai.key");
|
|
|
|
|
let encryption_key = load_or_generate_key(&key_path)?;
|
|
|
|
|
|
|
|
|
|
let http_client = reqwest::Client::new();
|
|
|
|
|
|
2026-04-13 07:48:27 +00:00
|
|
|
app.manage(AppState {
|
2026-04-13 12:20:45 +00:00
|
|
|
db: Arc::new(Mutex::new(conn)),
|
|
|
|
|
encryption_key,
|
|
|
|
|
http_client,
|
2026-04-13 07:48:27 +00:00
|
|
|
});
|
|
|
|
|
Ok(())
|
|
|
|
|
})
|
2026-04-13 07:58:20 +00:00
|
|
|
.invoke_handler(tauri::generate_handler![
|
|
|
|
|
commands::project::create_project,
|
|
|
|
|
commands::project::list_projects,
|
|
|
|
|
commands::project::get_project,
|
|
|
|
|
commands::project::update_project,
|
|
|
|
|
commands::project::delete_project,
|
2026-04-13 12:26:13 +00:00
|
|
|
commands::credential::set_tuleap_credentials,
|
|
|
|
|
commands::credential::get_tuleap_credentials,
|
|
|
|
|
commands::credential::delete_tuleap_credentials,
|
|
|
|
|
commands::credential::test_tuleap_connection,
|
2026-04-13 12:38:20 +00:00
|
|
|
commands::tracker::add_tracker,
|
|
|
|
|
commands::tracker::list_trackers,
|
|
|
|
|
commands::tracker::update_tracker,
|
|
|
|
|
commands::tracker::remove_tracker,
|
|
|
|
|
commands::tracker::get_tracker_fields,
|
|
|
|
|
commands::tracker::list_processed_tickets,
|
|
|
|
|
commands::poller::manual_poll,
|
|
|
|
|
commands::poller::get_queue_status,
|
2026-04-13 07:58:20 +00:00
|
|
|
])
|
2026-04-13 07:31:24 +00:00
|
|
|
.run(tauri::generate_context!())
|
|
|
|
|
.expect("error while running tauri application");
|
|
|
|
|
}
|
2026-04-13 12:20:45 +00:00
|
|
|
|
|
|
|
|
fn load_or_generate_key(path: &std::path::Path) -> Result<[u8; 32], Box<dyn std::error::Error>> {
|
|
|
|
|
use rand::RngCore;
|
|
|
|
|
if path.exists() {
|
|
|
|
|
let bytes = std::fs::read(path)?;
|
|
|
|
|
if bytes.len() != 32 {
|
|
|
|
|
return Err("Invalid key file size".into());
|
|
|
|
|
}
|
|
|
|
|
let mut key = [0u8; 32];
|
|
|
|
|
key.copy_from_slice(&bytes);
|
|
|
|
|
Ok(key)
|
|
|
|
|
} else {
|
|
|
|
|
let mut key = [0u8; 32];
|
|
|
|
|
rand::rngs::OsRng.fill_bytes(&mut key);
|
|
|
|
|
std::fs::write(path, &key)?;
|
|
|
|
|
Ok(key)
|
|
|
|
|
}
|
|
|
|
|
}
|