Skip to content

Commit e8c141d

Browse files
committed
feat: add acceleration consent and clearer errors
1 parent a6ba937 commit e8c141d

11 files changed

Lines changed: 312 additions & 50 deletions

File tree

‎src-tauri/src/core.rs‎

Lines changed: 63 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -913,6 +913,9 @@ impl AppCore {
913913
if enabled && git::git_version().is_none() {
914914
return Err("未检测到系统 Git".into());
915915
}
916+
if enabled && settings.consent_acknowledged_at.is_none() {
917+
return Err("首次开启加速前,请在 GitBoost 窗口中确认隐私提示".into());
918+
}
916919
if enabled && settings.route_scope == RouteScope::Allowlist && self.routes()?.is_empty() {
917920
return Err("仅加速清单为空,请先加入至少一个公开仓库".into());
918921
}
@@ -930,6 +933,14 @@ impl AppCore {
930933
self.snapshot()
931934
}
932935

936+
pub fn acknowledge_consent(&self) -> Result<AppSnapshot, String> {
937+
let _guard = self.lock.lock();
938+
let mut settings = self.settings()?;
939+
settings.consent_acknowledged_at = Some(Utc::now());
940+
atomic_write_json(&self.paths.settings, &settings)?;
941+
self.snapshot()
942+
}
943+
933944
fn select_current(
934945
&self,
935946
settings: &mut Settings,
@@ -1144,6 +1155,12 @@ impl AppCore {
11441155
let registered = git::include_registered(&self.paths.gitconfig);
11451156
let mut settings = self.settings()?;
11461157
let routes = self.routes()?;
1158+
let repaired_missing_consent =
1159+
settings.acceleration_enabled && settings.consent_acknowledged_at.is_none();
1160+
if repaired_missing_consent {
1161+
settings.acceleration_enabled = false;
1162+
settings.current_node_id = None;
1163+
}
11471164
let repaired_empty_allowlist = settings.acceleration_enabled
11481165
&& settings.route_scope == RouteScope::Allowlist
11491166
&& routes.is_empty();
@@ -1157,7 +1174,7 @@ impl AppCore {
11571174
settings.current_node_id = None;
11581175
}
11591176
if !registered && !settings.acceleration_enabled {
1160-
if repaired_empty_allowlist || repaired_disabled_state {
1177+
if repaired_missing_consent || repaired_empty_allowlist || repaired_disabled_state {
11611178
atomic_write_json(&self.paths.settings, &settings)?;
11621179
}
11631180
return Ok(());
@@ -1998,6 +2015,7 @@ mod tests {
19982015
let settings = Settings {
19992016
acceleration_enabled: true,
20002017
current_node_id: Some(replacement.id.clone()),
2018+
consent_acknowledged_at: Some(Utc::now()),
20012019
..Settings::default()
20022020
};
20032021
atomic_write_json(&core.paths.routes, &vec![route.clone()]).unwrap();
@@ -2093,6 +2111,7 @@ mod tests {
20932111
let settings = Settings {
20942112
acceleration_enabled: true,
20952113
current_node_id: Some(FASTGIT_REWRITE_BASE.into()),
2114+
consent_acknowledged_at: Some(Utc::now()),
20962115
..Settings::default()
20972116
};
20982117
atomic_write_json(&core.paths.settings, &settings).unwrap();
@@ -2783,6 +2802,7 @@ mod tests {
27832802
let directory = tempfile::tempdir().unwrap();
27842803
let core = AppCore::new(directory.path().to_path_buf()).unwrap();
27852804
core.add_route("openai/codex").unwrap();
2805+
core.acknowledge_consent().unwrap();
27862806

27872807
assert_eq!(
27882808
core.set_acceleration(true).unwrap_err(),
@@ -2831,6 +2851,38 @@ mod tests {
28312851
assert!(restored_allowlist.settings.current_node_id.is_none());
28322852
}
28332853

2854+
#[test]
2855+
fn acceleration_requires_privacy_consent_once() {
2856+
const MARKER: &str = "GITBOOST_CONSENT_GATE_STATE_CHILD";
2857+
if rerun_with_isolated_git(
2858+
"core::tests::acceleration_requires_privacy_consent_once",
2859+
MARKER,
2860+
) {
2861+
return;
2862+
}
2863+
let directory = tempfile::tempdir().unwrap();
2864+
let core = AppCore::new(directory.path().to_path_buf()).unwrap();
2865+
// 常规配置操作(添加路由)不能影响同意状态
2866+
core.add_route("openai/codex").unwrap();
2867+
assert!(core.settings().unwrap().consent_acknowledged_at.is_none());
2868+
2869+
assert_eq!(
2870+
core.set_acceleration(true).unwrap_err(),
2871+
"首次开启加速前,请在 GitBoost 窗口中确认隐私提示"
2872+
);
2873+
assert!(!core.settings().unwrap().acceleration_enabled);
2874+
2875+
let acknowledged = core.acknowledge_consent().unwrap();
2876+
assert!(acknowledged.settings.consent_acknowledged_at.is_some());
2877+
assert!(!acknowledged.settings.acceleration_enabled);
2878+
2879+
// 同意后不再要求确认,错误回到线路本身
2880+
assert_eq!(
2881+
core.set_acceleration(true).unwrap_err(),
2882+
"没有通过真实 Git 检测的可用节点"
2883+
);
2884+
}
2885+
28342886
#[test]
28352887
fn startup_clears_a_stale_selection_while_disabled() {
28362888
let directory = tempfile::tempdir().unwrap();
@@ -3452,6 +3504,16 @@ mod tests {
34523504
);
34533505

34543506
core.add_route("openai/codex").unwrap();
3507+
assert_eq!(
3508+
core.set_acceleration(true).unwrap_err(),
3509+
"首次开启加速前,请在 GitBoost 窗口中确认隐私提示"
3510+
);
3511+
core.acknowledge_consent().unwrap();
3512+
drop(core);
3513+
3514+
// 真实文件持久化和重新加载后,同意状态仍然有效,不依赖进程内 mock 状态。
3515+
let core = AppCore::new(root.clone()).unwrap();
3516+
assert!(core.settings().unwrap().consent_acknowledged_at.is_some());
34553517
let enabled = core.set_acceleration(true).unwrap();
34563518
assert!(enabled.settings.acceleration_enabled);
34573519
let node_id = enabled

‎src-tauri/src/downloads.rs‎

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,17 @@ pub fn prepare_target(original_url: &str, node: &NodeDefinition) -> Result<Downl
3434
})
3535
}
3636

37-
pub fn probe_and_open(target: DownloadTarget) -> Result<DownloadTarget, String> {
38-
probe(&target)?;
39-
open_in_browser(&target.accelerated_url)?;
37+
pub enum DownloadOpenError {
38+
Probe { node_name: String, detail: String },
39+
Browser(String),
40+
}
41+
42+
pub fn probe_and_open(target: DownloadTarget) -> Result<DownloadTarget, DownloadOpenError> {
43+
probe(&target).map_err(|detail| DownloadOpenError::Probe {
44+
node_name: target.node_name.clone(),
45+
detail,
46+
})?;
47+
open_in_browser(&target.accelerated_url).map_err(DownloadOpenError::Browser)?;
4048
Ok(target)
4149
}
4250

@@ -102,7 +110,6 @@ fn probe(target: &DownloadTarget) -> Result<(), String> {
102110
Duration::from_secs(8),
103111
PROBE_MAX_BYTES,
104112
)
105-
.map_err(|error| format!("无法通过 {} 获取此文件:{error}", target.node_name))
106113
}
107114

108115
#[cfg(test)]

0 commit comments

Comments
 (0)