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)]
17#[serde(rename_all = "camelCase")]
18pub struct KeysBatch {
19    pub steam_id: String,
20    pub steam_api_key: String,
21    pub rawg_api_key: String,
22    pub gemini_api_key: String,
23    pub gamebrain_api_key: String,
24    pub nexus_api_key: String,
25}
26
27/// Recupera todos os secrets configurados em lote.
28///
29/// Busca e descriptografa todas as credenciais armazenadas,
30/// retornando strings vazias para secrets não configurados.
31#[tauri::command]
32pub fn get_secrets(app: AppHandle) -> Result<KeysBatch, AppError> {
33    Ok(KeysBatch {
34        steam_id: database::get_secret(&app, "steam_id")?,
35        steam_api_key: database::get_secret(&app, "steam_api_key")?,
36        rawg_api_key: database::get_secret(&app, "rawg_api_key")?,
37        gemini_api_key: database::get_secret(&app, "gemini_api_key")?,
38        gamebrain_api_key: database::get_secret(&app, "gamebrain_api_key")?,
39        nexus_api_key: database::get_secret(&app, "nexus_api_key")?,
40    })
41}
42
43/// Configura múltiplos secrets numa única operação.
44///
45/// Permite atualizar várias credenciais simultaneamente.
46/// Mantém a compatibilidade com o objeto JSON enviado pelo frontend.
47#[tauri::command]
48pub fn set_secrets(
49    app: AppHandle,
50    steam_id: Option<String>,
51    steam_api_key: Option<String>,
52    rawg_api_key: Option<String>,
53    gemini_api_key: Option<String>,
54    gamebrain_api_key: Option<String>,
55    nexus_api_key: Option<String>,
56) -> Result<(), AppError> {
57    // Helper para salvar ou deletar baseado no valor
58    let save_or_delete = |key: &str, value: Option<String>| -> Result<(), AppError> {
59        if let Some(v) = value {
60            let trimmed = v.trim();
61            if trimmed.is_empty() {
62                database::delete_secret(&app, key)?;
63            } else {
64                database::set_secret(&app, key, trimmed)?;
65            }
66        }
67        Ok(())
68    };
69
70    save_or_delete("steam_id", steam_id)?;
71    save_or_delete("steam_api_key", steam_api_key)?;
72    save_or_delete("rawg_api_key", rawg_api_key)?;
73    save_or_delete("gemini_api_key", gemini_api_key)?;
74    save_or_delete("gamebrain_api_key", gamebrain_api_key)?;
75    save_or_delete("nexus_api_key", nexus_api_key)?;
76    Ok(())
77}
78
79/// Define um secret individual por nome de chave.
80///
81/// Versão genérica que permite configurar qualquer secret suportado fornecendo nome e valor.
82#[tauri::command]
83pub fn set_secret(app: AppHandle, key_name: String, key_value: String) -> Result<(), AppError> {
84    let trimmed_val = key_value.trim();
85
86    if trimmed_val.is_empty() {
87        return Err(AppError::ValidationError(
88            "Valor não pode ser vazio".to_string(),
89        ));
90    }
91
92    database::set_secret(&app, &key_name, trimmed_val)
93}
94
95/// Recupera um secret individual por nome de chave.
96///
97/// Busca e descriptografa uma credencial específica do banco.
98#[tauri::command]
99pub fn get_secret(app: AppHandle, key_name: String) -> Result<String, AppError> {
100    database::get_secret(&app, &key_name)
101}
102
103/// Remove permanentemente um secret do banco.
104///
105/// Exclui a credencial criptografada do banco de dados. Operação irreversível.
106#[tauri::command]
107pub fn delete_secret(app: AppHandle, key_name: String) -> Result<(), AppError> {
108    database::delete_secret(&app, &key_name)
109}
110
111/// Lista todos os nomes de secrets suportados pelo sistema.
112///
113/// Retorna lista com os nomes de todas as credenciais que podem
114/// ser configuradas, útil para validação no frontend.
115#[tauri::command]
116pub fn list_secrets() -> Vec<String> {
117    database::list_supported_keys()
118        .into_iter()
119        .map(|s| s.to_string())
120        .collect()
121}