1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
|
use anyhow::{Context, Result};
use serde::{Deserialize, Serialize};
use std::fs;
use std::path::PathBuf;
use crate::models::UserInfo;
/// Session data stored to disk
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SessionData {
pub server_url: String,
pub token: String,
pub user: UserInfo,
pub remember_server: bool,
pub remember_username: bool,
pub saved_username: Option<String>,
#[serde(default)]
pub default_printer_id: Option<i64>,
/// Remember last-used printer (may differ from default_printer_id if user overrides per-print)
#[serde(default)]
pub last_printer_id: Option<i64>,
}
/// Manages user session and credentials
pub struct SessionManager {
config_path: PathBuf,
current_session: Option<SessionData>,
}
impl SessionManager {
/// Create a new session manager
pub fn new() -> Self {
let config_dir = dirs::config_dir()
.unwrap_or_else(|| PathBuf::from("."))
.join("beepzone");
// Ensure config directory exists
let _ = fs::create_dir_all(&config_dir);
let config_path = config_dir.join("session.json");
let mut manager = Self {
config_path,
current_session: None,
};
// Try to load existing session
let _ = manager.load_session();
manager
}
/// Save a new session
pub fn save_session(&mut self, session: SessionData) -> Result<()> {
self.current_session = Some(session.clone());
let json = serde_json::to_string_pretty(&session).context("Failed to serialize session")?;
fs::write(&self.config_path, json).context("Failed to write session file")?;
log::info!("Session saved to {:?}", self.config_path);
Ok(())
}
/// Load session from disk
pub fn load_session(&mut self) -> Result<()> {
if !self.config_path.exists() {
return Ok(());
}
let json = fs::read_to_string(&self.config_path).context("Failed to read session file")?;
let session: SessionData =
serde_json::from_str(&json).context("Failed to parse session file")?;
self.current_session = Some(session);
log::info!("Session loaded from {:?}", self.config_path);
Ok(())
}
/// Clear the current session
pub fn clear_session(&mut self) -> Result<()> {
self.current_session = None;
if self.config_path.exists() {
fs::remove_file(&self.config_path).context("Failed to remove session file")?;
log::info!("Session file removed");
}
Ok(())
}
/// Get the current session
pub fn get_session(&self) -> Option<&SessionData> {
self.current_session.as_ref()
}
/// Check if there's a valid session
#[allow(dead_code)]
pub fn has_session(&self) -> bool {
self.current_session.is_some()
}
/// Get the saved server URL (if remember_server is enabled)
pub fn get_saved_server_url(&self) -> Option<String> {
self.current_session
.as_ref()
.filter(|s| s.remember_server)
.map(|s| s.server_url.clone())
}
/// Get the saved username (if remember_username is enabled)
pub fn get_saved_username(&self) -> Option<String> {
self.current_session
.as_ref()
.and_then(|s| s.saved_username.clone())
}
/// Update session with new token (for token refresh)
#[allow(dead_code)]
pub fn update_token(&mut self, new_token: String) -> Result<()> {
if let Some(session) = &mut self.current_session {
let mut updated_session = session.clone();
updated_session.token = new_token;
self.save_session(updated_session)?;
}
Ok(())
}
/// Update default printer ID
pub fn update_default_printer(&mut self, printer_id: Option<i64>) -> Result<()> {
if let Some(session) = &mut self.current_session {
let mut updated_session = session.clone();
updated_session.default_printer_id = printer_id;
self.save_session(updated_session)?;
}
Ok(())
}
/// Get default printer ID
pub fn get_default_printer_id(&self) -> Option<i64> {
self.current_session
.as_ref()
.and_then(|s| s.default_printer_id)
}
/// Get last-used printer ID for printing
pub fn get_last_print_preferences(&self) -> Option<i64> {
if let Some(session) = &self.current_session {
session.last_printer_id
} else {
None
}
}
}
impl Default for SessionManager {
fn default() -> Self {
Self::new()
}
}
|