Skip to main content

game_manager_lib/commands/
settings.rs

1//! Módulo de gerenciamento de configurações e secrets.
2//!
3//! Fornece interface para armazenar e recuperar credenciais
4//! sensíveis (API keys, IDs) de forma segura usando criptografia.
5//! Todos os secrets são criptografados usando AES-256-GCM antes de serem salvas no banco de dados.
6//! A chave de criptografia é derivada de características únicas via `security::init_security()`.
7
8use crate::database;
9use crate::errors::AppError;
10use serde::{Deserialize, Serialize};
11use tauri::AppHandle;
12
13/// Lote de todas as API keys configuradas no sistema.
14///
15/// Usado para retornar múltiplos secrets de uma vez para o frontend.
16#[derive(Serialize, Deserialize)]
17pub struct KeysBatch {
18    #[serde(rename = "steamId")]
19    pub steam_id: String,
20    #[serde(rename = "steamApiKey")]
21    pub steam_api_key: String,
22    #[serde(rename = "rawgApiKey")]
23    pub rawg_api_key: String,
24    #[serde(rename = "geminiApiKey")]
25    pub gemini_api_key: String,
26    #[serde(rename = "gamebrainApiKey")]
27    pub gamebrain_api_key: String,
28}
29
30/// Recupera todos os secrets configurados em lote.
31///
32/// Busca e descriptografa todas as credenciais armazenadas,
33/// retornando strings vazias para secrets não configurados.
34#[tauri::command]
35pub fn get_secrets(app: AppHandle) -> Result<KeysBatch, AppError> {
36    Ok(KeysBatch {
37        steam_id: database::get_secret(&app, "steam_id")?,
38        steam_api_key: database::get_secret(&app, "steam_api_key")?,
39        rawg_api_key: database::get_secret(&app, "rawg_api_key")?,
40        gemini_api_key: database::get_secret(&app, "gemini_api_key")?,
41        gamebrain_api_key: database::get_secret(&app, "gamebrain_api_key")?,
42    })
43}
44
45/// Configura múltiplos secrets numa única operação.
46///
47/// Permite atualizar várias credenciais simultaneamente.
48/// Mantém a compatibilidade com o objeto JSON enviado pelo frontend.
49#[tauri::command]
50pub fn set_secrets(
51    app: AppHandle,
52    steam_id: Option<String>,
53    steam_api_key: Option<String>,
54    rawg_api_key: Option<String>,
55    gemini_api_key: Option<String>,
56    gamebrain_api_key: Option<String>,
57) -> Result<(), AppError> {
58    // Helper para salvar ou deletar baseado no valor
59    let save_or_delete = |key: &str, value: Option<String>| -> Result<(), AppError> {
60        if let Some(v) = value {
61            let trimmed = v.trim();
62            if trimmed.is_empty() {
63                database::delete_secret(&app, key)?;
64            } else {
65                database::set_secret(&app, key, trimmed)?;
66            }
67        }
68        Ok(())
69    };
70
71    save_or_delete("steam_id", steam_id)?;
72    save_or_delete("steam_api_key", steam_api_key)?;
73    save_or_delete("rawg_api_key", rawg_api_key)?;
74    save_or_delete("gemini_api_key", gemini_api_key)?;
75    save_or_delete("gamebrain_api_key", gamebrain_api_key)?;
76
77    Ok(())
78}
79
80/// Define um secret individual por nome de chave.
81///
82/// Versão genérica que permite configurar qualquer secret suportado fornecendo nome e valor.
83#[tauri::command]
84pub fn set_secret(app: AppHandle, key_name: String, key_value: String) -> Result<(), AppError> {
85    let trimmed_val = key_value.trim();
86
87    if trimmed_val.is_empty() {
88        return Err(AppError::ValidationError(
89            "Valor não pode ser vazio".to_string(),
90        ));
91    }
92
93    database::set_secret(&app, &key_name, trimmed_val)
94}
95
96/// Recupera um secret individual por nome de chave.
97///
98/// Busca e descriptografa uma credencial específica do banco.
99#[tauri::command]
100pub fn get_secret(app: AppHandle, key_name: String) -> Result<String, AppError> {
101    database::get_secret(&app, &key_name)
102}
103
104/// Remove permanentemente um secret do banco.
105///
106/// Exclui a credencial criptografada do banco de dados. Operação irreversível.
107#[tauri::command]
108pub fn delete_secret(app: AppHandle, key_name: String) -> Result<(), AppError> {
109    database::delete_secret(&app, &key_name)
110}
111
112/// Lista todos os nomes de secrets suportados pelo sistema.
113///
114/// Retorna lista com os nomes de todas as credenciais que podem
115/// ser configuradas, útil para validação no frontend.
116#[tauri::command]
117pub fn list_secrets() -> Vec<String> {
118    database::list_supported_keys()
119        .into_iter()
120        .map(|s| s.to_string())
121        .collect()
122}