mirror of
https://github.com/thegeneralist01/archivr
synced 2026-07-22 03:05:32 +02:00
feat: cookie consent extension support (ARCHIVR_COOKIE_EXT)
Mirrors the uBlock Origin Lite integration exactly: Backend: - singlefile.rs: resolve_cookie_ext_config() reads ARCHIVR_COOKIE_CONSENT (default true) + ARCHIVR_COOKIE_EXT path; extension paths comma-joined into --load-extension / --disable-extensions-except so uBlock and cookie ext can coexist; SaveResult.cookie_ext_skipped tracks miss - database.rs: cookie_ext_enabled column on instance_settings (DEFAULT 1); idempotent ALTER TABLE migration; get/update wired through - capture.rs: CaptureConfig.cookie_ext_enabled: Option<bool>; threaded to singlefile::save(); cookie_ext_skipped surfaced in CaptureResult - routes.rs: CaptureBody + UpdateInstanceSettingsBody get cookie_ext_enabled; capture handler resolves effective value (body overrides global); notes_json only includes skipped fields that are true; GET instance-settings includes cookie_ext_available from env path check Frontend: - api.js: submitCapture forwards cookie_ext_enabled - SettingsView.jsx: 'I Still Don't Care About Cookies' card in Extensions tab; always-active toggle (user can disable even when ext not installed); amber 'Not configured' hint + ARCHIVR_COOKIE_EXT guidance when unavailable - CaptureDialog.jsx: 'Block cookie banners' toggle in Advanced options; always shown with amber hint when ext not configured; defaults from global setting Operator setup: download + unzip the extension from GitHub releases, set ARCHIVR_COOKIE_EXT=/path/to/unpacked/ext. No Node daemon needed.
This commit is contained in:
parent
a6ca24b846
commit
52effb60f6
10 changed files with 260 additions and 70 deletions
|
|
@ -654,6 +654,7 @@ struct CaptureBody {
|
|||
ublock_enabled: Option<bool>,
|
||||
/// Distil to article content via Readability before archiving. Absent = false.
|
||||
reader_mode: Option<bool>,
|
||||
cookie_ext_enabled: Option<bool>,
|
||||
}
|
||||
|
||||
#[derive(Debug, serde::Deserialize)]
|
||||
|
|
@ -733,26 +734,27 @@ async fn capture_handler(
|
|||
let conn = database::open_or_initialize(&mounted.archive_path)?;
|
||||
let job_uid = database::create_capture_job(&conn, &archive_id)?;
|
||||
drop(conn);
|
||||
|
||||
// Load cookie rules and global uBlock setting from the auth DB.
|
||||
let (cookie_rules, global_ublock) = {
|
||||
// Load cookie rules and global uBlock / cookie-ext settings from the auth DB.
|
||||
let (cookie_rules, global_ublock, global_cookie_ext) = {
|
||||
match database::open_auth_db(&state.auth_db_path) {
|
||||
Ok(conn) => {
|
||||
let rules = database::list_cookie_rules(&conn).unwrap_or_default();
|
||||
let ublock = database::get_instance_settings(&conn)
|
||||
.map(|s| s.ublock_enabled)
|
||||
.unwrap_or(true);
|
||||
(rules, ublock)
|
||||
let settings = database::get_instance_settings(&conn);
|
||||
let ublock = settings.as_ref().map(|s| s.ublock_enabled).unwrap_or(true);
|
||||
let cookie_ext = settings.map(|s| s.cookie_ext_enabled).unwrap_or(true);
|
||||
(rules, ublock, cookie_ext)
|
||||
}
|
||||
Err(_) => (vec![], true),
|
||||
Err(_) => (vec![], true, true),
|
||||
}
|
||||
};
|
||||
// Per-capture body overrides global; if body doesn't specify, use the global setting.
|
||||
// The resolved bool is then passed as Some(_) to singlefile, overriding the env var.
|
||||
let effective_ublock = body.ublock_enabled.unwrap_or(global_ublock);
|
||||
let effective_cookie_ext = body.cookie_ext_enabled.unwrap_or(global_cookie_ext);
|
||||
let capture_config = capture::CaptureConfig {
|
||||
cookie_rules,
|
||||
ublock_enabled: Some(effective_ublock),
|
||||
cookie_ext_enabled: Some(effective_cookie_ext),
|
||||
reader_mode: body.reader_mode.unwrap_or(false),
|
||||
};
|
||||
|
||||
|
|
@ -773,10 +775,19 @@ async fn capture_handler(
|
|||
database::update_capture_job_status(&conn, &job_uid_bg, "running", None, None, None).ok();
|
||||
match capture::perform_capture(&archive_paths, &locator, Some(&archive_id_bg), quality.as_deref(), &capture_config) {
|
||||
Ok(result) => {
|
||||
let notes = if result.ublock_skipped {
|
||||
Some(r#"{"ublock_skipped":true}"#)
|
||||
} else {
|
||||
let mut notes_map = serde_json::Map::new();
|
||||
if result.ublock_skipped {
|
||||
notes_map.insert("ublock_skipped".into(), serde_json::Value::Bool(true));
|
||||
}
|
||||
if result.cookie_ext_skipped {
|
||||
notes_map.insert("cookie_ext_skipped".into(), serde_json::Value::Bool(true));
|
||||
}
|
||||
let notes_str;
|
||||
let notes: Option<&str> = if notes_map.is_empty() {
|
||||
None
|
||||
} else {
|
||||
notes_str = serde_json::Value::Object(notes_map).to_string();
|
||||
Some(¬es_str)
|
||||
};
|
||||
database::update_capture_job_status(
|
||||
&conn,
|
||||
|
|
@ -1043,9 +1054,15 @@ async fn get_instance_settings_handler(
|
|||
.filter(|s| !s.is_empty())
|
||||
.map(|p| std::path::Path::new(&p).is_dir())
|
||||
.unwrap_or(false);
|
||||
let cookie_ext_available = std::env::var("ARCHIVR_COOKIE_EXT")
|
||||
.ok()
|
||||
.filter(|s| !s.is_empty())
|
||||
.map(|p| std::path::Path::new(&p).is_dir())
|
||||
.unwrap_or(false);
|
||||
let mut val = serde_json::to_value(&settings).unwrap_or_default();
|
||||
if let Some(obj) = val.as_object_mut() {
|
||||
obj.insert("ublock_ext_available".into(), serde_json::Value::Bool(ublock_ext_available));
|
||||
obj.insert("cookie_ext_available".into(), serde_json::Value::Bool(cookie_ext_available));
|
||||
}
|
||||
Ok(Json(val))
|
||||
}
|
||||
|
|
@ -1063,6 +1080,7 @@ async fn update_instance_settings_handler(
|
|||
if let Some(v) = body.open_registration_enabled { settings.open_registration_enabled = v; }
|
||||
if let Some(v) = body.default_entry_visibility { settings.default_entry_visibility = v; }
|
||||
if let Some(v) = body.ublock_enabled { settings.ublock_enabled = v; }
|
||||
if let Some(v) = body.cookie_ext_enabled { settings.cookie_ext_enabled = v; }
|
||||
database::update_instance_settings(&conn, &settings)?;
|
||||
Ok(StatusCode::NO_CONTENT)
|
||||
}
|
||||
|
|
@ -1393,6 +1411,7 @@ struct UpdateInstanceSettingsBody {
|
|||
open_registration_enabled: Option<bool>,
|
||||
default_entry_visibility: Option<u32>,
|
||||
ublock_enabled: Option<bool>,
|
||||
cookie_ext_enabled: Option<bool>,
|
||||
}
|
||||
|
||||
async fn admin_list_users(
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
40
crates/archivr-server/static/assets/index-DNXMjfPb.js
Normal file
40
crates/archivr-server/static/assets/index-DNXMjfPb.js
Normal file
File diff suppressed because one or more lines are too long
|
|
@ -4,7 +4,7 @@
|
|||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<title>Archivr</title>
|
||||
<script type="module" crossorigin src="/assets/index-Cxnyn8_x.js"></script>
|
||||
<script type="module" crossorigin src="/assets/index-DNXMjfPb.js"></script>
|
||||
<link rel="stylesheet" crossorigin href="/assets/index-C0BIEdow.css">
|
||||
</head>
|
||||
<body>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue